参考正点原子例程实现。
- 先配置FreeRTOSConfig.h
/***************************************************************************************************************/
/* FreeRTOS与运行时间和任务状态收集有关的配置选项 */
/***************************************************************************************************************/
#define configGENERATE_RUN_TIME_STATS 1 //为1时启用运行时间统计功能
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ConfigureTimeForRunTimeStats()//定时器3提供时间统计的时基,频率为10K,即周期为100us
#define portGET_RUN_TIME_COUNTER_VALUE() FreeRTOSRunTimeTicks //获取时间统计时间值
#define configUSE_TRACE_FACILITY 1 //为1启用可视化跟踪调试
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 //与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
- 定时器中断设置运行时间基准
TIM_HandleTypeDef htim7;
/*******************************************************************************
功能: 用于调试OS任务运行时间
输入参数:200us
返回值:
修改建议:
*******************************************************************************/
void ConfigureTimeForRunTimeStats(void)
{
FreeRTOSRunTimeTicks=0;
STM_TIM_Base_Init(TIM7,200,24);
}
/*******************************************************************************
功能: 定时器初始化
输入参数:TIM_TypeDef TIM15 period 周期,psc 分频 范围0-65535
返回值:
修改建议:
*******************************************************************************/
void STM_TIM_Base_Init(TIM_TypeDef *tim,uint16_t period,uint16_t psc)
{
if (tim==TIM7)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim7.Instance = TIM7;
htim7.Init.Prescaler = psc-1;
htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
htim7.Init.Period = period-1;
htim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim7.Init.RepetitionCounter = 0;
htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim7, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_Base_Start_IT(&htim7);
}
}
/*******************************************************************************
功能: 定时器初始化回调函数
输入参数:TIM_TypeDef TIM15
返回值:
修改建议:
*******************************************************************************/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if (htim_base->Instance==TIM7)
{
__HAL_RCC_TIM7_CLK_ENABLE();
HAL_NVIC_SetPriority(TIM7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM7_IRQn);
}
}
/*******************************************************************************
功能: 定时器初始化注销
输入参数:TIM_TypeDef TIM15
返回值:
修改建议:
*******************************************************************************/
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
if (htim_base->Instance==TIM7)
{
__HAL_RCC_TIM7_CLK_DISABLE();
HAL_NVIC_DisableIRQ(TIM7_IRQn);
}
}
/*******************************************************************************
功能: 定时器中断回调函数 TIM3为H桥的上臂PWM输出,中断周期为100us, 100个PWM脉冲
输入参数:
返回值:
修改建议:
*******************************************************************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM16)
{
HAL_IncTick();
}
else if (htim->Instance == TIM7)
{
FreeRTOSRunTimeTicks++;
}
}
void TIM7_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim7);
}
- 任务中添加查询打印代码
uint8_t pressure_ch=1;
uint16_t pressure_count=0;
/* USER CODE BEGIN Header_StartTask_Key */
char InfoBuffer[1000]; //保存信息的数组
char RunTimeInfo[400]; //保存任务运行时间信
void StartTask_Key(void const * argument)
{
/* USER CODE BEGIN StartTask_Key */
uint32_t TotalRunTime;
UBaseType_t ArraySize,x;
TaskStatus_t *StatusArray;
printf("/********第一步:函数uxTaskGetSystemState()的使用**********/\r\n");
ArraySize=uxTaskGetNumberOfTasks(); //获取系统任务数量
StatusArray=pvPortMalloc(ArraySize*sizeof(TaskStatus_t));//申请内存
if(StatusArray!=NULL) //内存申请成功
{
ArraySize=uxTaskGetSystemState((TaskStatus_t* )StatusArray, //任务信息存储数组
(UBaseType_t )ArraySize, //任务信息存储数组大小
(uint32_t* )&TotalRunTime);//保存系统总的运行时间
printf("TaskName\t\tPriority\t\tTaskNumber\t\t\r\n");
for(x=0;x<ArraySize;x++)
{
//通过串口打印出获取到的系统任务的有关信息,比如任务名称、
//任务优先级和任务编号。
printf("%s\t\t%d\t\t\t%d\t\t\t\r\n",
StatusArray[x].pcTaskName,
(int)StatusArray[x].uxCurrentPriority,
(int)StatusArray[x].xTaskNumber);
}
}
vPortFree(StatusArray); //释放内存
printf("/**************************结束***************************/\r\n");
//第二步:函数vTaskGetInfo()的使用
TaskHandle_t TaskHandle;
TaskStatus_t TaskStatus;
printf("/************第二步:函数vTaskGetInfo()的使用**************/\r\n");
TaskHandle=xTaskGetHandle("Task_Key"); //根据任务名获取任务句柄。
//获取Task_Key的任务信息
vTaskGetInfo((TaskHandle_t )TaskHandle, //任务句柄
(TaskStatus_t* )&TaskStatus, //任务信息结构体
(BaseType_t )pdTRUE, //允许统计任务堆栈历史最小剩余大小
(eTaskState )eInvalid); //函数自己获取任务运行壮态
//通过串口打印出指定任务的有关信息。
printf("任务名: %s\r\n",TaskStatus.pcTaskName);
printf("任务编号: %d\r\n",(int)TaskStatus.xTaskNumber);
printf("任务壮态: %d\r\n",TaskStatus.eCurrentState);
printf("任务当前优先级: %d\r\n",(int)TaskStatus.uxCurrentPriority);
printf("任务基优先级: %d\r\n",(int)TaskStatus.uxBasePriority);
printf("任务堆栈基地址: %#x\r\n",(int)TaskStatus.pxStackBase);
printf("任务堆栈历史剩余最小值:%d\r\n",TaskStatus.usStackHighWaterMark);
printf("/**************************结束***************************/\r\n");
//第三步:函数eTaskGetState()的使用
eTaskState TaskState;
char TaskInfo[10];
printf("/***********第三步:函数eTaskGetState()的使用*************/\r\n");
TaskHandle=xTaskGetHandle("Task_Key"); //根据任务名获取任务句柄。
TaskState=eTaskGetState(TaskHandle); //获取query_task任务的任务壮态
memset(TaskInfo,0,10);
switch((int)TaskState)
{
case 0:
sprintf(TaskInfo,"Running");
break;
case 1:
sprintf(TaskInfo,"Ready");
break;
case 2:
sprintf(TaskInfo,"Suspend");
break;
case 3:
sprintf(TaskInfo,"Delete");
break;
case 4:
sprintf(TaskInfo,"Invalid");
break;
}
printf("任务壮态值:%d,对应的壮态为:%s\r\n",TaskState,TaskInfo);
printf("/**************************结束**************************/\r\n");
//第四步:函数vTaskList()的使用
printf("/*************第三步:函数vTaskList()的使用*************/\r\n");
vTaskList(InfoBuffer); //获取所有任务的信息
printf("%s\r\n",InfoBuffer); //通过串口打印所有任务的信息
printf("/**************************结束**************************/\r\n");
memset(RunTimeInfo,0,400); //信息缓冲区清零
vTaskGetRunTimeStats(RunTimeInfo); //获取任务运行时间信息
printf("任务名\t\t\t运行时间\t运行所占百分比\r\n");
printf("%s\r\n",RunTimeInfo);
/* Infinite loop */
for (;;)
{
if((Pressure_Get(1)&0X8000)!=0x8000)
{
memset(RunTimeInfo,0,400); //信息缓冲区清零
vTaskGetRunTimeStats(RunTimeInfo); //获取任务运行时间信息
printf("任务名\t\t\t运行时间\t运行所占百分比\r\n");
printf("%s\r\n",RunTimeInfo);
}
if((Pressure_Get(2)&0X8000)!=0x8000)
{
}
osDelay(50);
}
/* USER CODE END StartTask_Key */
}
- 打印效果
TaskName Priority TaskNumber
Task_Key 2 4
Task_Disp 1 2
IDLE 0 6
defaultTask 0 1
Tmr Svc 2 7
Task_Driver 2 3
Task_App 2 5
/结束*/
/第二步:函数vTaskGetInfo()的使用**/
任务名: Task_Key
任务编号: 4
任务壮态: 0
任务当前优先级: 2
任务基优先级: 2
任务堆栈基地址: 0x20001728
任务堆栈历史剩余最小值:936
/结束*/
/第三步:函数eTaskGetState()的使用**/
任务壮态值:0,对应的壮态为:Running
/结束/
/第三步:函数vTaskList()的使用/
Task_Key X 2 936 4
Task_Disp R 1 118 2
defaultTask R 0 118 1
IDLE R 0 119 6
Tmr Svc B 2 211 7
Task_Driver B 2 70 3
Task_App B 2 102 5
/结束/
任务名 运行时间 运行所占百分比
Task_Key 672 96%
Task_Disp 0 <1%
IDLE 0 <1%
defaultTask 0 <1%
Tmr Svc 4 <1%
Task_Driver 49 7%
Task_App 6 <1%