一、实现目标
STM32F103 基于Hal库跑FreeRTOS,统计CPU占比 找出有问题的任务,类似实现一个windows 系统的任务查看界面。
代码运行结果如下
二、思路
记录任务的时间点,相减获得任务所占用的时间,所得时间/总时间,得到该CPU占比。
三、实现函数
只需要调用一个vTaskGetRunTimeStats:获得任务的运行信息,形式为可读的字符串。
void vTaskGetRunTimeStats( signed char *pcWriteBuffer );
四、操作步骤
1、连接串口后,在freertos.c里面定义一个全局变量,存在所有任务的栈的信息,注意,pcWriteBuffer必须足够大。
static signed char pcWriteBuffer[200];
2、保证如下条件成立
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
一般条件1和条件3是默认成立的,如果条件2的宏定义是0(#define configUSE_STATS_FORMATTING_FUNCTIONS 0),需要配置STM32CubeMX,将其使能,如下图所示。
3、使能钩子函数,USE_IDLE_HOOK
在配置STM32CubeMX将其使能,如下图所示。
4、使能 configGENERATE_RUN_TIME_STATS
在配置STM32CubeMX将其使能,如下图所示。
5、重新生成代码
配置成功后,configGENERATE_RUN_TIME_STATS 会定义为1。
#define configGENERATE_RUN_TIME_STATS 1
6、定时器的驱动文件driver_timer.c 添加如下2个函数。uint64_t system_get_ns(void),实现弱函数unsigned long getRunTimeCounterValue(void)。
/********************************************************************** * 函数名称: system_get_ns * 功能描述: 获得系统时间(单位ns) * 输入参数: 无 * 输出参数: 无 * 返 回 值: 系统时间(单位ns) * 修改日期 版本号 修改人 修改内容 **********************************************************************/ uint64_t system_get_ns(void) { extern TIM_HandleTypeDef htim4; TIM_HandleTypeDef *hHalTim = &htim4; uint64_t ns = HAL_GetTick(); uint64_t cnt; uint64_t reload; cnt = __HAL_TIM_GET_COUNTER(hHalTim); reload = __HAL_TIM_GET_AUTORELOAD(hHalTim); ns *= 1000000; ns += cnt * 1000000 / reload; return ns; } /* 返回系统启动后过了多少时间(单位us) */ unsigned long getRunTimeCounterValue(void) { return system_get_ns() / 1000; }
7、在钩子函数void vApplicationIdleHook( void )改成如下代码,获得任务的运行信息及打印结果。
void vApplicationIdleHook( void ) { int i; //vTaskList(pcWriteBuffer); vTaskGetRunTimeStats(pcWriteBuffer); for (i = 0; i < 16; i++) printf("-"); printf(" "); printf("%s ", pcWriteBuffer); }
8、运行结果,可统计CPU占比,从占比大中,找出有问题的任务。
9、备注-源码和环境
源码链接https://download.csdn.net/download/m0_37371085/88768311
单片机:STM32F103c8tx
keil版本:5.32
STM32CubeMX版本:6.8.1