|
本帖最后由 apleilx 于 2021-6-9 13:57 编辑
一直以为队列是RTOS任务同步速度最慢的API,今天特地测试了下threadx任务同步直接颠覆了我的认知。
测试分为两部分,请求同步的任务为最高优先级,发送同步的分别为低优先级任务和ISR。
测试平台 IAR8.401。 芯片AT32F407,程序在0等待区执行。
程序执行时钟数通过 DWT获取:
- #define bsp_cpu_clks_get() DWT->CYCCNT
复制代码
时间统计变量
- typedef struct
- {
- volatile uint32_t u_tick;
- volatile uint32_t powerup_time_cnt;
- timer_pulse_type pulse;
- sig_time_type sig_time;
- TIME_Type rtc_time;
复制代码
高优先级任务等待
- while (1)
- {
- bsp_dwt_check();
-
- // 信号量测试
- sys_st.api_tick.sem_req = 1;
- tx_semaphore_get(&os_obj.sem_tst, TX_WAIT_FOREVER);
- sys_st.api_tick.sem_rcv_tick = bsp_cpu_clks_get();
- sys_st.api_tick.sem_tick_amount =
- sys_st.api_tick.sem_rcv_tick - sys_st.api_tick.sem_send_tick;
-
- // 事件组测试
- sys_st.api_tick.event_req = 1;
- tx_event_flags_get(&os_obj.event_tst,
- 0xFFFF,
- TX_OR_CLEAR,
- &sys_st.api_tick.event_dat ,
- TX_WAIT_FOREVER);
- sys_st.api_tick.event_rcv_tick = bsp_cpu_clks_get();
- sys_st.api_tick.event_tick_amount =
- sys_st.api_tick.event_rcv_tick - sys_st.api_tick.event_send_tick;
-
- // 队列测试
- sys_st.api_tick.quene_req = 1;
- tx_queue_receive(&os_obj.quene_tst,
- sys_st.api_tick.quene_dat,
- TX_WAIT_FOREVER);
- sys_st.api_tick.quene_rcv_tick = bsp_cpu_clks_get();
- sys_st.api_tick.quene_tick_amount =
- sys_st.api_tick.quene_rcv_tick - sys_st.api_tick.quene_send_tick;
-
- // 互斥量获取
- /*
- sys_st.api_tick.mutex_req_tick = bsp_cpu_clks_get();
- tx_mutex_get(&os_obj.mutex_common, TX_WAIT_FOREVER);
- sys_st.api_tick.mutex_get_tick_amount = bsp_cpu_clks_get() - sys_st.api_tick.mutex_req_tick;
-
- sys_st.api_tick.mutex_req_tick = bsp_cpu_clks_get();
- tx_mutex_put(&os_obj.mutex_common);
- sys_st.api_tick.mutex_put_tick_amount = bsp_cpu_clks_get() - sys_st.api_tick.mutex_req_tick;
- */
-
- // 互斥量等待获取
- if(sys_st.api_tick.b_mutex_busy)
- {
- sys_st.api_tick.mutex_req = 1;
- tx_mutex_get(&os_obj.mutex_common, TX_WAIT_FOREVER);
-
- sys_st.api_tick.mutex_get_tick = bsp_cpu_clks_get();
- sys_st.api_tick.mutex_get_tick_amount =
- sys_st.api_tick.mutex_get_tick - sys_st.api_tick.mutex_put_tick;
-
- tx_mutex_put(&os_obj.mutex_common);
- }
- }
复制代码
低优先级任务发送
- void os_sync_send(void)
- {
- if(sys_st.api_tick.sem_req)
- {
- sys_st.api_tick.sem_send_tick = bsp_cpu_clks_get();
- tx_semaphore_put(&os_obj.sem_tst);
- }
-
- if(sys_st.api_tick.event_req)
- {
- sys_st.api_tick.event_send_tick = bsp_cpu_clks_get();
- tx_event_flags_set(&os_obj.event_tst, 1, TX_OR);
- }
-
- if(sys_st.api_tick.quene_req)
- {
- sys_st.api_tick.quene_send_tick = bsp_cpu_clks_get();
- tx_queue_send(&os_obj.quene_tst, sys_st.api_tick.quene_dat, TX_NO_WAIT);
- }
-
- if(!sys_st.api_tick.b_mutex_busy)
- {
- tx_mutex_get(&os_obj.mutex_common, TX_WAIT_FOREVER);
- sys_st.api_tick.b_mutex_busy = 1;
- }
-
- if(sys_st.api_tick.mutex_req)
- {
- sys_st.api_tick.mutex_put_tick = bsp_cpu_clks_get();
- tx_mutex_put(&os_obj.mutex_common);
- }
-
- }
复制代码 测试结果如下:
我原以为信号方式是最快的,结果它最慢,队列反而是最快的。互斥量的测试方法是,让低优先级任务先获取信号量,然后高优先级任务请求,测得时间是 低优先级任务释放到高优先级获取成功的时间。
另外,当互斥信号量空闲时,获取仅71时钟,释放68时钟。
=====================================================================================
ISR发送测试
- void isr_sync_send(void)
- {
- if(sys_st.api_tick.sem_req)
- {
- sys_st.api_tick.sem_send_tick = bsp_cpu_clks_get();
- tx_semaphore_put(&os_obj.sem_tst);
- }
-
- if(sys_st.api_tick.event_req)
- {
- sys_st.api_tick.event_send_tick = bsp_cpu_clks_get();
- tx_event_flags_set(&os_obj.event_tst, 1, TX_OR);
- }
-
- if(sys_st.api_tick.quene_req)
- {
- sys_st.api_tick.quene_send_tick = bsp_cpu_clks_get();
- tx_queue_send(&os_obj.quene_tst, sys_st.api_tick.quene_dat, TX_NO_WAIT);
- }
- }
复制代码
ISR中发送同步,信号量表现好多了,队列依然是最快的。
互斥量在ISR不可用,不测试
由于threadx不同的宏定义对执行效率有重大影响,本测试仅代表API的相对速度。测试得到的时钟数数据是反复观测的,结果应该是准确的。
测试用tx_user.h配置
tx_user.h
(11.78 KB, 下载次数: 0)
|
|