Skip to content

Commit e115dab

Browse files
committed
add sys pref frameworks
1 parent a1e8651 commit e115dab

File tree

5 files changed

+298
-0
lines changed

5 files changed

+298
-0
lines changed

examples/utest/testcases/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ rsource "posix/Kconfig"
1717
rsource "mm/Kconfig"
1818
rsource "tmpfs/Kconfig"
1919
rsource "smp_call/Kconfig"
20+
rsource "perf/Kconfig"
2021
endif
2122

2223
endmenu
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
menu "System Performance Testcase"
2+
3+
config UTEST_SYS_PERF_TC
4+
bool "system performance test"
5+
default n
6+
7+
config UTEST_SYS_PERF_TC_COUNT
8+
int "Test the number of cycles"
9+
default 1000
10+
depends on UTEST_SYS_PERF_TC
11+
12+
config UTEST_HWTIMER_DEV_NAME
13+
string "Hardware timer device name"
14+
default "timer0"
15+
depends on RT_USING_HWTIMER && UTEST_SYS_PERF_TC
16+
help
17+
Specify the hardware timer device name used for context switch testing (e.g., timer0).
18+
19+
config UTEST_SYS_IRQ_LATENCY
20+
bool "system IRQ LATENCY test"
21+
default n
22+
depends on RT_USING_HWTIMER && UTEST_SYS_PERF_TC
23+
24+
endmenu
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Import('rtconfig')
2+
from building import *
3+
4+
cwd = GetCurrentDir()
5+
src = Glob('*.c')
6+
CPPPATH = [cwd]
7+
8+
# if GetDepend(['UTEST_SYS_IRQ_LATENCY']):
9+
# src += ['irq_latency_tc.c']
10+
11+
group = DefineGroup('utestcases', src, depend = ['UTEST_SYS_PERF_TC'], CPPPATH = CPPPATH)
12+
13+
Return('group')
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
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 <rtservice.h>
14+
#include <utest.h>
15+
#include <utest_assert.h>
16+
#include <perf_tc.h>
17+
18+
#define RET_INT 0
19+
#define RET_DECIMALS 1
20+
21+
#define GET_INT(num) split_double(num, RET_INT)
22+
#define GET_DECIMALS(num) split_double(num, RET_DECIMALS)
23+
24+
static rt_device_t hw_dev = RT_NULL;
25+
static rt_hwtimerval_t timeout_s = {0};
26+
27+
typedef rt_err_t (*testcase_function)(rt_perf_t *perf);
28+
testcase_function test_func_ptrs[] =
29+
{
30+
context_switch_test,
31+
rt_perf_thread_sem,
32+
rt_perf_thread_event,
33+
rt_perf_thread_mq,
34+
rt_perf_thread_mbox,
35+
/* The interrupt delay test requires modifying the timer and setting the callback to be executed last. */
36+
#ifdef UTEST_SYS_IRQ_LATENCY
37+
rt_perf_irq_latency, /* Timer Interrupt Source */
38+
#endif
39+
RT_NULL
40+
};
41+
42+
static rt_uint32_t rt_perf_get_timer_us(void)
43+
{
44+
rt_hwtimerval_t timer_val = {0};
45+
if (hw_dev && rt_device_read(hw_dev, 0, &timer_val, sizeof(rt_hwtimerval_t)))
46+
{
47+
return (rt_uint32_t)(timer_val.sec * 1000000u + timer_val.usec); /* return us */
48+
}
49+
return 0;
50+
}
51+
52+
void rt_perf_start_impl(rt_perf_t *perf, rt_hwtimerval_t *timeout)
53+
{
54+
if (hw_dev)
55+
{
56+
if (timeout == RT_NULL)
57+
timeout = &timeout_s;
58+
rt_device_write(hw_dev, 0, timeout, sizeof(rt_hwtimerval_t));
59+
}
60+
perf->begin_time = rt_perf_get_timer_us();
61+
}
62+
63+
void rt_perf_stop(rt_perf_t *perf)
64+
{
65+
perf->real_time = rt_perf_get_timer_us() - perf->begin_time;
66+
67+
if(perf->local_modify) perf->local_modify(perf);
68+
if (perf->real_time > perf->max_time)
69+
{
70+
perf->max_time = perf->real_time;
71+
}
72+
73+
if (perf->real_time < perf->min_time)
74+
{
75+
perf->min_time = perf->real_time;
76+
}
77+
78+
perf->count++;
79+
perf->tot_time += perf->real_time;
80+
81+
if(hw_dev)
82+
rt_device_control(hw_dev, HWTIMER_CTRL_STOP, NULL);
83+
}
84+
85+
static rt_int32_t split_double(double num, rt_uint32_t type)
86+
{
87+
if (type == RET_INT)
88+
{
89+
return (rt_int32_t)num;
90+
}
91+
else if (type == RET_DECIMALS)
92+
{
93+
return (rt_int32_t)((num - (rt_int32_t)num) * 10000);
94+
}
95+
else
96+
{
97+
return (-1);
98+
}
99+
100+
return (-1);
101+
}
102+
103+
void rt_perf_dump( rt_perf_t *perf)
104+
{
105+
static rt_uint32_t test_index = 1;
106+
char avg_str[10] = {0};
107+
if(perf->dump_head)
108+
{
109+
rt_kprintf("Test No | Test Name | Count | Total Time (us) | Max Time (us) | Min Time (us) | Avg Time (us)\n");
110+
rt_kprintf("--------|----------------------|-------|-----------------|---------------|---------------|--------------\n");
111+
perf->dump_head = RT_FALSE;
112+
}
113+
if (perf->count)
114+
perf->avg_time = (double)perf->tot_time / perf->count;
115+
else
116+
perf->avg_time = 0.0;
117+
118+
rt_sprintf(avg_str, "%u.%04u", GET_INT(perf->avg_time), GET_DECIMALS(perf->avg_time));
119+
120+
rt_kprintf("%7u | %-20s | %5u | %15u | %13u | %13u | %12s\n",
121+
test_index++,
122+
perf->name,
123+
perf->count,
124+
perf->tot_time,
125+
perf->max_time,
126+
perf->min_time,
127+
avg_str);
128+
}
129+
130+
static void rt_perf_clear(rt_perf_t *perf)
131+
{
132+
perf->local_modify = NULL;
133+
perf->begin_time = 0;
134+
perf->real_time = 0;
135+
perf->tot_time = 0;
136+
perf->max_time = 0;
137+
perf->min_time = RT_UINT32_MAX;
138+
perf->count = 0;
139+
perf->avg_time = 0;
140+
perf->tmp_time = 0;
141+
}
142+
143+
static void rt_perf_all_test(void)
144+
{
145+
146+
rt_perf_t *perf_data = rt_malloc(sizeof(rt_perf_t));
147+
if (perf_data == RT_NULL)
148+
{
149+
return;
150+
}
151+
perf_data->lock = rt_mutex_create("perf", RT_IPC_FLAG_PRIO);
152+
perf_data->dump_head = RT_TRUE;
153+
rt_kprintf("\n === Performance Test Results Start ===\n");
154+
for (int i = 0; test_func_ptrs[i] != RT_NULL; i++)
155+
{
156+
rt_perf_clear(perf_data);
157+
if (test_func_ptrs[i](perf_data) != RT_EOK)
158+
{
159+
LOG_E("%s test fail",perf_data->name);
160+
continue;
161+
}
162+
}
163+
rt_kprintf("\n === Performance Test Results End ===\n");
164+
rt_mutex_delete(perf_data->lock);
165+
rt_free(perf_data);
166+
}
167+
168+
static rt_err_t utest_tc_init(void)
169+
{
170+
int ret = RT_EOK;
171+
172+
hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
173+
if (hw_dev == RT_NULL)
174+
{
175+
ret = RT_ERROR;
176+
LOG_E("hwtimer sample run failed! can't find %s device!", UTEST_HWTIMER_DEV_NAME);
177+
return ret;
178+
}
179+
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
180+
if (ret != RT_EOK)
181+
{
182+
LOG_E("open %s device failed!", UTEST_HWTIMER_DEV_NAME);
183+
return ret;
184+
}
185+
186+
timeout_s.sec = 10; /* No modification is necessary here, use the fixed value */
187+
timeout_s.usec = 0;
188+
189+
return ret;
190+
}
191+
192+
static rt_err_t utest_tc_cleanup(void)
193+
{
194+
if(hw_dev) rt_device_close(hw_dev);
195+
return RT_EOK;
196+
}
197+
198+
static void testcase(void)
199+
{
200+
UTEST_UNIT_RUN(rt_perf_all_test);
201+
}
202+
203+
UTEST_TC_EXPORT(testcase, "testcase.pref.all", utest_tc_init, utest_tc_cleanup, 10);
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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
9+
*/
10+
11+
#ifndef PERF_TC_H__
12+
#define PERF_TC_H__
13+
14+
#include <rtthread.h>
15+
#include <rtdevice.h>
16+
#include <rtservice.h>
17+
#include <rttypes.h>
18+
19+
#define THREAD_STACK_SIZE 2048
20+
#define THREAD_PRIORITY 10
21+
#define THREAD_TIMESLICE 5
22+
typedef struct rt_perf
23+
{
24+
char name[64];
25+
volatile rt_uint32_t begin_time;
26+
volatile rt_uint32_t real_time;
27+
volatile rt_uint32_t tot_time;
28+
volatile rt_uint32_t max_time;
29+
volatile rt_uint32_t min_time;
30+
volatile rt_uint32_t count;
31+
volatile double avg_time;
32+
volatile rt_uint32_t tmp_time; /* tmp */
33+
rt_mutex_t lock;
34+
void (*local_modify)(struct rt_perf *perf); // 注意此处也需写完整类型名
35+
rt_bool_t dump_head;
36+
#ifdef UTEST_SYS_IRQ_LATENCY
37+
void *user_data;
38+
#endif
39+
} rt_perf_t;
40+
41+
void rt_perf_start_impl(rt_perf_t *perf, rt_hwtimerval_t *timeout);
42+
void rt_perf_stop(rt_perf_t *perf);
43+
void rt_perf_dump( rt_perf_t *perf);
44+
45+
static inline void rt_perf_start(rt_perf_t *perf)
46+
{
47+
rt_perf_start_impl(perf, RT_NULL);
48+
}
49+
50+
rt_err_t context_switch_test(rt_perf_t *perf);
51+
rt_err_t rt_perf_irq_latency(rt_perf_t *perf);
52+
rt_err_t rt_perf_thread_sem(rt_perf_t *perf);
53+
rt_err_t rt_perf_thread_event(rt_perf_t *perf);
54+
rt_err_t rt_perf_thread_mq(rt_perf_t *perf);
55+
rt_err_t rt_perf_thread_mbox(rt_perf_t *perf);
56+
57+
#endif /* PERF_TC_H__ */

0 commit comments

Comments
 (0)