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 #include <perf_tc.h>
16 
17 static rt_device_t hw_dev = RT_NULL;
18 static rt_sem_t complete_sem = RT_NULL;
19 static rt_hwtimerval_t timeout = {0};
20 static rt_perf_t *perf_local = RT_NULL;
21 
modify_time(rt_perf_t * perf)22 static void modify_time(rt_perf_t *perf)
23 {
24     if(perf)
25         perf->real_time = perf->real_time - perf->tmp_time;
26 }
27 
timer_callback(rt_device_t dev,rt_size_t size)28 static rt_err_t timer_callback(rt_device_t dev, rt_size_t size)
29 {
30     rt_perf_stop(perf_local);
31     if (perf_local->count >= UTEST_SYS_PERF_TC_COUNT)
32     {
33         rt_sem_release(complete_sem);
34         return RT_EOK;
35     }
36     rt_perf_start_impl(perf_local, &timeout);
37     return RT_EOK;
38 }
39 
rt_perf_irq_latency(rt_perf_t * perf)40 rt_err_t rt_perf_irq_latency(rt_perf_t *perf)
41 {
42 # if __STDC_VERSION__ >= 199901L
43     rt_strcpy(perf->name,__func__);
44 #else
45     rt_strcpy(perf->name,"rt_perf_irq_latency");
46 #endif
47     int ret = RT_EOK;
48     rt_hwtimer_mode_t mode = HWTIMER_MODE_PERIOD;
49 
50     perf_local = perf;
51     hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
52     if (hw_dev == RT_NULL)
53     {
54         ret = RT_ERROR;
55         LOG_E("hwtimer sample run failed! can't find %s device!", UTEST_HWTIMER_DEV_NAME);
56         return ret;
57     }
58 
59     complete_sem = rt_sem_create("complete", 0, RT_IPC_FLAG_FIFO);
60     timeout.sec = 0;
61     timeout.usec = 50;   /* No modification is necessary here, use the fixed value */
62 
63     rt_mutex_take(perf->lock,RT_WAITING_FOREVER);
64     perf_local->tmp_time = (rt_uint32_t)(timeout.sec * 1000000u + timeout.usec);
65     perf_local->local_modify = modify_time;
66     rt_mutex_release(perf->lock);
67 
68     rt_device_set_rx_indicate(hw_dev, timer_callback);
69     rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, (void *)&mode);
70 
71     rt_perf_start_impl(perf_local, &timeout);
72 
73     rt_sem_take(complete_sem, RT_WAITING_FOREVER);
74     rt_perf_dump(perf_local);
75     rt_sem_delete(complete_sem);
76     rt_device_close(hw_dev);
77 
78     return RT_EOK;
79 }
80 
81