Skip to content

Commit 35f9429

Browse files
committed
add irq latency test code
1 parent 206ee0a commit 35f9429

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

examples/utest/testcases/pref/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ config UTEST_SYS_CONTEXT_SWITCH
2929
bool "system context switch test"
3030
default n
3131

32+
config UTEST_SYS_IRQ_LATENCY
33+
bool "system context switch test"
34+
default n
35+
depends on RT_USING_HWTIMER
36+
3237
endmenu

examples/utest/testcases/pref/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ CPPPATH = [cwd]
88
if GetDepend(['UTEST_SYS_CONTEXT_SWITCH']):
99
src += ['context_switch.c']
1010

11+
if GetDepend(['UTEST_SYS_IRQ_LATENCY']):
12+
src += ['irq_latency.c']
13+
1114
group = DefineGroup('utestcases', src, depend = ['UTEST_SYS_PREF_TC'], CPPPATH = CPPPATH)
1215

1316
Return('group')
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (c) 2006-2025, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-07-03 rcitach test case for irq latency
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include <utest.h>
14+
#include <utest_assert.h>
15+
16+
#define IRQ_LATENCY 1000
17+
18+
static rt_device_t hw_dev = RT_NULL;
19+
static rt_sem_t test_sem = RT_NULL;
20+
static rt_hwtimerval_t timeout_s = {0};
21+
volatile static rt_bool_t complete = RT_FALSE;
22+
volatile static uint16_t irq_latency_count = 0;
23+
static rt_hwtimerval_t irq_time[IRQ_LATENCY];
24+
25+
static rt_size_t get_timer_us(rt_hwtimerval_t *timeout_s)
26+
{
27+
if (hw_dev)
28+
return rt_device_read(hw_dev, 0, timeout_s, sizeof(rt_hwtimerval_t));
29+
return 0;
30+
}
31+
32+
static rt_err_t timer_callback(rt_device_t dev, rt_size_t size)
33+
{
34+
get_timer_us(&irq_time[irq_latency_count]);
35+
irq_latency_count++;
36+
rt_device_control(hw_dev, HWTIMER_CTRL_STOP, RT_NULL);
37+
if (irq_latency_count >= IRQ_LATENCY)
38+
{
39+
complete = RT_TRUE;
40+
rt_sem_release(test_sem);
41+
return RT_EOK;
42+
}
43+
44+
rt_device_write(hw_dev, 0, &timeout_s, sizeof(rt_hwtimerval_t));
45+
return RT_EOK;
46+
}
47+
48+
void irq_latency_test(void)
49+
{
50+
uint32_t total_time = 0;
51+
timeout_s.sec = 0;
52+
timeout_s.usec = 1000;
53+
rt_device_write(hw_dev, 0, &timeout_s, sizeof(rt_hwtimerval_t));
54+
55+
rt_sem_take(test_sem, RT_WAITING_FOREVER);
56+
for (int i = 0; i < IRQ_LATENCY; i++)
57+
{
58+
total_time += ((irq_time[i].sec - timeout_s.sec) * 1000000) + (irq_time[i].usec - timeout_s.usec);
59+
}
60+
61+
LOG_I("Total time for %d interrupts: %u us", IRQ_LATENCY, total_time);
62+
LOG_I("Average interrupt latency: %u us", total_time / IRQ_LATENCY);
63+
}
64+
65+
static rt_err_t utest_tc_init(void)
66+
{
67+
rt_hwtimer_mode_t mode = HWTIMER_MODE_PERIOD;
68+
69+
test_sem = rt_sem_create("irq_test", 0, RT_IPC_FLAG_FIFO);
70+
if (test_sem == RT_NULL)
71+
{
72+
rt_kprintf("Failed to create semaphore\n");
73+
return -RT_ERROR;
74+
}
75+
76+
hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
77+
if (hw_dev == RT_NULL)
78+
{
79+
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", UTEST_HWTIMER_DEV_NAME);
80+
rt_sem_delete(test_sem);
81+
return -RT_ERROR;
82+
}
83+
84+
rt_err_t ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
85+
if (ret != RT_EOK)
86+
{
87+
rt_kprintf("open %s device failed!\n", UTEST_HWTIMER_DEV_NAME);
88+
rt_sem_delete(test_sem);
89+
return ret;
90+
}
91+
92+
rt_device_set_rx_indicate(hw_dev, timer_callback);
93+
rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, (void *)&mode);
94+
95+
return RT_EOK;
96+
}
97+
98+
static rt_err_t utest_tc_cleanup(void)
99+
{
100+
complete = RT_FALSE;
101+
irq_latency_count = 0;
102+
rt_memset(irq_time, 0, sizeof(irq_time));
103+
if (test_sem)
104+
{
105+
rt_sem_delete(test_sem);
106+
test_sem = RT_NULL;
107+
}
108+
#ifdef USING_HWTIME_AS_TIME_REF
109+
if (hw_dev) rt_device_close(hw_dev);
110+
#endif
111+
return RT_EOK;
112+
}
113+
114+
static void testcase(void)
115+
{
116+
UTEST_UNIT_RUN(irq_latency_test);
117+
}
118+
119+
UTEST_TC_EXPORT(testcase, "testcase.pref.irq_latency", utest_tc_init, utest_tc_cleanup, 10);

0 commit comments

Comments
 (0)