Freertos 的任务状态和运行时间串口打印

参考正点原子例程实现。

  1. 先配置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个函数

  1. 定时器中断设置运行时间基准
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);
}
  1. 任务中添加查询打印代码
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 */
}



  1. 打印效果

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%

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS是一个用于嵌入式系统的实时操作系统。在FreeRTOS中,任务是系统中最基本的执行单位。下面是关于FreeRTOS任务创建和使用的一些基本信息: 1. 在FreeRTOS中创建任务的步骤如下: - 使用xTaskCreate()函数创建任务,指定任务函数、任务名称、堆栈大小和优先级等参数。 - 在任务函数中定义任务的行为和逻辑。 - 使用vTaskStartScheduler()函数启动调度器,开始任务调度。 2. 任务函数的定义: - 任务函数是一个无返回值、无参数的函数,它将在任务创建后立即执行。 - 任务函数应该包含一个无限循环,以便任务能够不断地执行。 3. 任务的优先级: - FreeRTOS使用优先级来确定任务的执行顺序。具有较高优先级的任务将在具有较低优先级的任务之前执行。 - 可以使用宏定义configMAX_PRIORITIES来定义系统支持的最大优先级数。 4. 任务挂起和恢复: - 可以使用vTaskSuspend()函数将任务挂起,使其暂停执行。 - 可以使用vTaskResume()函数恢复被挂起的任务,使其继续执行。 5. 任务删除: - 可以使用vTaskDelete()函数删除一个已经创建的任务。 这些是FreeRTOS任务创建和使用的基本知识。在实际应用中,还可以使用其他FreeRTOS提供的功能和API来管理和控制任务的执行。请注意,具体的实现细节可能会因为不同的系统和编译器而有所差异,建议参考FreeRTOS官方文档和示例代码进行更详细的学习和了解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值