完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
本章节为大家讲解ThreadX原装任务统计分析功能的实现,支持MDK,IAR和GCC。
16.1 ThreadX的任务统计分析实现原理 对于Cortex-M内核,带有DWT时钟周期计数器,比如芯片主频是100MHz,那么DWT统计的时钟周期分辨率就是10ns。 ThreadX就是借助此功能实现任务统计分析,使用简单,仅需使能就可以使用。M3,M4和M7内核都带这个功能,而M0内核不带,使用中要注意。 16.2 ThreadX的任务统计分析功能移植 这里以移植到MDK为例进行说明,其它IAR,GCC的移植方法是一样的。 16.2.1 添加任务分析代码 从ThreadX 内核V6.1.7版本开始,加入了任务统计分析功能,位于源码软件包的如下路径: ThreadXutilityexecution_profile_kit 。 按照前面章节的移植方法,升级ThreadX内核的版本到V6.1.7后,添加此文件即可。 别忘了添加相应路径: 16.2.2 设置宏定义 C文件要添加宏定义:TX_EXECUTION_PROFILE_ENABLE, TX_CORTEX_M_EPK 汇编文件要添加宏定义:TX_EXECUTION_PROFILE_ENABLE,TX_ENABLE_EXECUTION_CHANGE_NOTIFY 对于MDK AC5,Misc Controls加上 –cpreproc 16.2.3 使能DWT时钟周期计时器 默认情况下,ThreadX的移植文件tx_initialize_low_level.s带了DWT时钟周期计数器的使能: /* Enable the cycle count register. */ LDR r0, =0xE0001000 ; Build address of DWT register LDR r1, [r0] ; Pickup the current value ORR r1, r1, #1 ; Set the CYCCNTENA bit STR r1, [r0] ; Enable the cycle count register 保险起见,在bsp.c文件也调用了函数bsp_InitDWT()做初始化。 16.2.4 展示任务统计方法 Threadx提供了三个64bit的全局变量统计时间信息,单位是系统时钟计数器,比如主频是100MHz,那么单位就是10ns。 _tx_execution_thread_time_total 统计从上电开始,所有任务总的运行时间。 _tx_execution_idle_time_total 统计从上电开始,总的空闲时间。 _tx_execution_isr_time_total 统计从上电开始,中断服务程序总的执行实现。 为了方便统计CPU利用率,可以采用: _tx_execution_thread_time_total/(_tx_execution_thread_time_total + _tx_execution_idle_time_total + _tx_execution_isr_time_total) 但这种统计不能反应CPU利用率瞬时变化,所以做了一个瞬时的统计方法,每200ms统计一次: /* ********************************************************************************************************* * 函 数 名: AppTaskStart * 功能说明: 启动任务。 * 形 参: thread_input 是在创建该任务时传递的形参 * 返 回 值: 无 优 先 级: 2 ********************************************************************************************************* */ static void AppTaskStart (ULONG thread_input) { EXECUTION_TIME TolTime, IdleTime, deltaTolTime, deltaIdleTime; uint32_t uiCount = 0; (void)thread_input; /* 内核开启后,恢复HAL里的时间基准 */ HAL_ResumeTick(); /* 外设初始化 */ bsp_Init(); /* 创建任务 */ AppTaskCreate(); /* 创建任务间通信机制 */ AppObjCreate(); /* 计算CPU利用率 */ IdleTime = _tx_execution_idle_time_total; TolTime = _tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total; while (1) { /* 需要周期性处理的程序,对应裸机工程调用的SysTick_ISR */ bsp_ProPer1ms(); /* CPU利用率统计 */ uiCount++; if(uiCount == 200) { uiCount = 0; deltaIdleTime = _tx_execution_idle_time_total - IdleTime; deltaTolTime = _tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total - TolTime; OSCPUUsage = (double)deltaIdleTime/deltaTolTime; OSCPUUsage = 100- OSCPUUsage*100; IdleTime = _tx_execution_idle_time_total; TolTime = _tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total; } tx_thread_sleep(1); } } 任务信息统一通过函数DispTaskInfo进行打印: /* ********************************************************************************************************* * 函 数 名: DispTaskInfo * 功能说明: 将ThreadX任务信息通过串口打印出来 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ static void DispTaskInfo(void) { TX_THREAD *p_tcb; /* 定义一个任务控制块指针 */ p_tcb = &AppTaskStartTCB; /* 打印标题 */ App_Printf("===============================================================rn"); App_Printf("CPU利用率 = %5.2f%%rn", OSCPUUsage); App_Printf("任务执行时间 = %.9fsrn", (double)_tx_execution_thread_time_total/SystemCoreClock); App_Printf("空闲执行时间 = %.9fsrn", (double)_tx_execution_idle_time_total/SystemCoreClock); App_Printf("中断执行时间 = %.9fsrn", (double)_tx_execution_isr_time_total/SystemCoreClock); App_Printf("系统总执行时间 = %.9fsrn", (double)(_tx_execution_thread_time_total + _tx_execution_idle_time_total + _tx_execution_isr_time_total)/SystemCoreClock); App_Printf("===============================================================rn"); App_Printf(" 任务优先级 任务栈大小 当前使用栈 最大栈使用 任务名rn"); App_Printf(" Prio StackSize CurStack MaxStack Tasknamern"); /* 遍历任务控制列表TCB list),打印所有的任务的优先级和名称 */ while (p_tcb != (TX_THREAD *)0) { App_Printf(" %2d %5d %5d %5d %srn", p_tcb->tx_thread_priority, p_tcb->tx_thread_stack_size, (int)p_tcb->tx_thread_stack_end - (int)p_tcb->tx_thread_stack_ptr, (int)p_tcb->tx_thread_stack_end - (int)p_tcb->tx_thread_stack_highest_ptr, p_tcb->tx_thread_name); p_tcb = p_tcb->tx_thread_created_next; if(p_tcb == &AppTaskStartTCB) break; } } 效果: 16.3 IAR的ThreadX插件实现 IAR和MDK的实现一样,移植了V6.1.7或者以上版本后,添加统计分析文件即可,剩下就是使能IAR的ThreadX插件:
16.4 实验例程 配套例子: V6-3011_ThreadX Task Statistics 实验目的: ThreadX原装任务统计分析功能 实验内容: 1、共创建了如下几个任务,通过按下按键K1可以通过串口或者RTT打印任务堆栈使用情况 ======================================================== CPU利用率 = 0.89% 任务执行时间 = 0.586484645s 空闲执行时间 = 85.504470575s 中断执行时间 = 0.173225395s 系统总执行时间 = 86.264180615s ======================================================= 任务优先级 任务栈大小 当前使用栈 最大栈使用 任务名 Prio StackSize CurStack MaxStack Taskname 2 4092 303 459 App Task Start 5 4092 167 167 App Msp Pro 4 4092 167 167 App Task UserIF 5 4092 167 167 App Task COM 0 1020 191 191 System Timer Thread 串口软件可以使用SecureCRT或者H7-TOOL RTT查看打印信息。 App Task Start任务 :启动任务,这里用作BSP驱动包处理。 App Task MspPro任务 :消息处理,这里用作LED闪烁。 App Task UserIF任务 :按键消息处理。 App Task COM任务 :这里用作LED闪烁。 System Timer Thread任务:系统定时器任务 2、 (1) 凡是用到printf函数的全部通过函数App_Printf实现。 (2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。 3、默认上电是通过串口打印信息,如果使用RTT打印信息 (1) MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可 #define Enable_RTTViewer 1 (2) Embedded Studio继续使用此宏定义为0, 因为Embedded Studio仅制作了调试状态RTT方式查看。 串口打印信息方式(AC5,AC6和IAR): 波特率 115200,数据位 8,奇偶校验位无,停止位 1 RTT打印信息方式(AC5,AC6和IAR): Embedded Studio仅支持调试状态RTT打印: 由于Embedded Studio不支持中文,所以中文部分显示乱码,不用管。 程序执行框图: 16.5 总结 本章节主要为大家讲解了ThreadX原装的任务统计分析功能的实现,比较实用。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1570 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1515 浏览 1 评论
943 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
669 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1562 浏览 2 评论
1851浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
620浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
506浏览 3评论
511浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
492浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-13 10:35 , Processed in 0.762548 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号