使用rtos时内存对于单片机来说总是非常抠搜的。
任务分配多了浪费,少了跑不动。
最近看到这个监听任务还是很好用的。
废话不多说。开始操作
第一步在配置文件中打开这几个宏
#define configUSE_TRACE_FACILITY 1 /*为1时启用可视化跟踪调试*/
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* configUSE_TRACE_FACILITY和 configUSE_STATS_FORMATTING_FUNCTIONS都设置为 1,则再构建中包含编译 vTaskList()和 vTaskGetRunTimeStats()函数;*/
#define configGENERATE_RUN_TIME_STATS 1 //为1时打开运行时间统计功能
第二步 定义一下几个宏
extern volatile unsigned long long FreeRTOSRunTimeTicks;
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ConfigureTimerForRunTimeStats()
/*用来初始化任务运行时间信息统计功能的时间基准,时间基准一般由定时器来提供,并且要求此基准的精度是系统节拍精度的10倍以上*/
#define portGET_RUN_TIME_COUNTER_VALUE() FreeRTOSRunTimeTicks
/*用来获取统计任务运行时间信息的计数器值,利用此计数值来计算各任务运行时间的占空比*/
FreeRTOSRunTimeTicks
ConfigureTimerForRunTimeStats()
这个两没有别急
然后开个定时器
/*
*函数名称;Timer2_Init
*功能描述:初始化定时器2,并打开定时中断
*传入参数:ARR-计数周期
* RSC-预分频器值
*/
void Timer2_Init(uint16_t ARR,uint16_t RSC)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);/*开启内部时钟*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; /*不分频*/
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数*/
TIM_TimeBaseInitStructure.TIM_Period = ARR;//ARR-计数周期
TIM_TimeBaseInitStructure.TIM_Prescaler = ARR;//PSC-预分频数
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; /*重复计数器*/
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//中断使能
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; /*设置要配置的中断通道为 TIM2 的中断通道。*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /*使能中断通道*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;/*抢占优先级*/
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;/*响应优先级*/
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2,ENABLE);/*开启定时器*/
}
刚才那两个就来了
时钟节拍自己定 我用的时128MHZ的。
将节拍计数值归零,并调用定时器初始化函数,
在这里进中断的频率为128 000 000 /128/50 = 20KHZ,
满足基准的精度是系统节拍精度的10倍以上的要求
/*
*函数名称:ConfigureTimerForRunTimeStats
*功能描述:将节拍计数值归零,并调用定时器初始化函数,
在这里进中断的频率为128 000 000 /128/50 = 20KHZ,
满足基准的精度是系统节拍精度的10倍以上的要求
*/
volatile unsigned long long FreeRTOSRunTimeTicks = 0;
//用来获取统计任务运行时间信息的计数器值
void ConfigureTimerForRunTimeStats(void)
{
FreeRTOSRunTimeTicks = 0;
Timer2_Init(50-1,128-1);
}
void TIM2_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update)==SET)/*检查TIM2的更新事件标志位*/
{
FreeRTOSRunTimeTicks++;/*节拍计数值++*/
TIM_ClearFlag(TIM2,TIM_FLAG_Update);/*清除更新事件标志位*/
}
}
然后加个监听任务
主要就是获取相关信息然后用串口啥的输出到你能看到的地方
/*定义一个打印任务信息的任务*/
void Cpu_task(void *argument)
{
uint8_t CPU_RunInfo[512];
while (1)
{
memset(CPU_RunInfo, 0, 512);
vTaskList((char *)&CPU_RunInfo); //获取任务运行时间信息
DEBUG_MSG("---------------------------------------------\r\n");
DEBUG_MSG("任务名 任务状态 优先级 剩余栈 任务序号\r\n");
sprintf((char *)rcv_buff2, "%s\n", CPU_RunInfo);
DEBUG_MSG((char *)rcv_buff2);
DEBUG_MSG("---------------------------------------------\r\n");
memset(CPU_RunInfo, 0, 512);
vTaskGetRunTimeStats((char *)&CPU_RunInfo);
DEBUG_MSG("任务名 运行计数 使用率\r\n");
sprintf((char *)rcv_buff2, "%s\n", CPU_RunInfo);
DEBUG_MSG((char *)rcv_buff2);
DEBUG_MSG("---------------------------------------------\r\n\n");
vTaskDelay(5000); /* 延时5000个tick */
}
}
来看看效果,
舒服多了,完美。