实时操作系统FreeRTOS应用之任务调试信息获取

描述

1.任务相关函数

1.1获取任务状态函数vTaskGetInfo()

    void vTaskGetInfo( TaskHandle_t xTask,TaskStatus_t * pxTaskStatus,

                                  BaseType_t xGetFreeStackSpace, eTaskState eState );

函数功能:获取指定任务的状态,任务状态信息保存在pxTaskStatus中。
            使用此函数需要configUSE_TRACE_FACILITY == 1
形参:
          xTask  要获取的任务句柄
          pxTaskStatus  任务信息结构体变量
          xGetFreeStackSpace  常设置为pdTRUE,用来检测堆栈空间历史剩余最小值。值越小说明越近堆栈溢出。
          eState     保存任务运行状态。获取任务运行状态时间比较长,为了加快vTaskGetInfo函数执行可直接将                                TaskStatus_t中的字段eCurrentState就可以由用户直接赋值,参数eState就是要赋的值。若不考                          虑时间因素,可以直接将eState设置为eInvalid,这样任务状态信息就由函数vTaskGetInfo去获取。
返回值 无。

任务信息结构体TaskStatus_t

typedef struct xTASK_STATUS
{
       TaskHandle_t  xHandle;      //任务句柄                 
       const char  *pcTaskName ;   //任务名称                     
       UBaseType_t  xTaskNumber;  //任务编号              
       eTaskState  eCurrentState;  // 当前任务状态, eTaskState是枚举类型                   
       UBaseType_t  uxCurrentPriority; //当前优先级               
       UBaseType_t  uxBasePriority;  //任务基础优先级       
       uint32_t  ulRunTimeCounter;  //任务运行总时间    
       StackType_t  *pxStackBase;   //任务堆栈基地址  
      configSTACK_DEPTH_TYPE  usStackHighWaterMark;//从任务创建以来任务堆栈剩余的最小值,值越小接近                                                                                          0越有溢出风险  
} TaskStatus_t;

任务状态 eTaskState

typedef enum
{
   eRunning = 0,  //运行状态
   eReady,       //就绪   
   eBlocked,     //阻塞
   eSuspended,  //挂起  
    eDeleted,     //删除
   eInvalid      //无效
} eTaskState;

1.2 查询每个任务运行时间vTaskGetRunTimeStats()

void vTaskGetRunTimeStats( char * pcWriteBuffer )
形参 
            pcWriteBuffer  --- 保存任务时间信息的存储区,存储区要足够大来保存该信息
函数功能
        查询每个任务的运行时间。使用此函数需要( configGENERATE_RUN_TIME_STATS == 1 ) &&                                       (configUSE_STATS_FORMATTING_FUNCTIONS>0)&&(configSUPPORT_DYNAMIC_ALLOCATION == 1 ) 
        若 configGENERATE_RUN_TIME_STATS==1 的话还需要设置下面宏。
             portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(), 此宏用来初始化一个外设给统计功能提供时间基准,一般采用定时器。这个时基的分辩率一定要高于FreeRTOS的系统时钟,一般这个时基的时间精度比系统时钟高10~20倍就可以了。
            portGET_RUN_TIME_COUNTER_VALUE 或portALT_GET_RUN_TIME_COUNTER_VALUE这二者实现其中一个,这两个宏用于提供当前时基的时间值。

1.3 查询任务详细信息vTaskList() 

void vTaskList( char * pcWriteBuffer )
形参:
        char * pcWriteBuffer  --  保存任务状态信息。

函数功能:查询任务任务详细信息,使用此函数( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 )&&( configSUPPORT_DYNAMIC_ALLOCATION == 1 )。
表信息包括任务名称、任务状态、优先级、堆栈剩余空间大小、任务编号
任务状态: 运行状态(X)、阻塞(B)、就绪(R)、删除(D)、挂起(S)
任务编号:这个编码每个任务都是唯一的,当多个任务使用同一任务名时可以通过此编号来区分。

2 示例

2.1 创建任务

#define START_TASK_PRIO 1        //任务优先级
#define START_STK_SIZE 128       //任务堆栈大小
TaskHandle_t StartTask_Handler;   //任务句柄
void start_task(void *pvParameters);//任务函数

#define LED0_TASK_PRIO 2     //任务优先级,数字越大优先级越高
#define LED0_STK_SIZE 128     //任务堆栈大小
TaskHandle_t LED0Task_Handler; //任务句柄
void LED0_task(void);         //任务函数

#define Quer_TASK_PRIO 2     //任务优先级
#define Quer_STK_SIZE 128      //任务堆栈大小
TaskHandle_t QuerTask_Handler; //任务句柄
void Query_task(void);          //任务函数
int main()
{
	Beep_Init();//蜂鸣器初始化
	LED_Init();//LED初始化
	KEY_Init();
	Usart1_Init(115200);//串口1初始化
	/*创建任务*/
	xTaskCreate((TaskFunction_t)start_task,//任务函数
							(const char *)"start_task",//任务名称	
							(uint16_t)START_STK_SIZE,//堆栈大小
							NULL,           //传递给任务函数的参数
							(UBaseType_t)START_TASK_PRIO,//任务优先级
							(TaskHandle_t *)&StartTask_Handler//任务句柄
							);
	vTaskStartScheduler();     //开启任务调度		
}
/*开始任务函数*/
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();  //进入临界区
	//创建LED0任务
	xTaskCreate( (TaskFunction_t  )LED0_task,//任务函数
				(const char    *)"LED0_task",//任务名称
				 (uint16_t)LED0_STK_SIZE,//堆栈大小
					NULL,           //传递给任务函数的参数
				 (UBaseType_t   )LED0_TASK_PRIO,//任务优先级
				 (TaskHandle_t *)&LED0Task_Handler);//任务句柄
	xTaskCreate(  (TaskFunction_t )Query_task,//任务函数
				(const char    *)"Query_task",//任务名称
				(uint16_t )Quer_STK_SIZE,//堆栈大小
				NULL,           //传递给任务函数的参数
				(UBaseType_t    )Quer_TASK_PRIO,//任务优先级
				(TaskHandle_t  *)&QuerTask_Handler);//任务句柄
	vTaskDelete(StartTask_Handler); //删除开始任务	
	taskEXIT_CRITICAL();            //退出临界区						
}

2.2 任务1 程序正常运行LED指示灯

void LED0_task(void)
{
	while(1)
	{
		LED1=!LED1;
		Delay_Ms(500);
	}
}

2.3 任务2:通过按键查询任务状态

char RunTimeInfo[400];//保存任务信息
void Query_task(void)//任务函数
{
	u8 key;
	TaskStatus_t task_info;//保存任务信息
	while(1)
	{
		key=KEY_GetVal();
		if(key==1)//获取任务运行时间,任务运行时间FreeRTOSRunTimeTicks*50us
		{
			memset(RunTimeInfo,0,400);
			vTaskGetRunTimeStats(RunTimeInfo);//获取每个任务运行时间
			printf("%s\r\n",RunTimeInfo);
		}
		if(key==2)//获取任务状态
		{
			vTaskGetInfo(NULL,&task_info,pdTRUE,eInvalid);//获取当前任务状态
			printf("task name:%s\r\n",task_info.pcTaskName);//任务名
			printf("task num:%ld\r\n",task_info.xTaskNumber);//任务编号
			printf("task stat:%d\r\n",task_info.eCurrentState);//任务状态
			printf("task baseaddr:%p\r\n",task_info.pxStackBase);//任务堆栈基地址
			printf("task priority:%ld\r\n",task_info.uxBasePriority);//任务基础优先级
			printf("tast now priority:%ld\r\n",task_info.uxCurrentPriority);//任务当前优先级
			printf("tast memory size:%d\r\n",task_info.usStackHighWaterMark);//任务历史剩余堆栈最小空间
			printf("tast time:%d\r\n",task_info.ulRunTimeCounter);//任务运行总时间	
		}
		if(key==3)//查询任务详细信息
		{
			memset(RunTimeInfo,0,400);
			vTaskList(RunTimeInfo);//获取任务状态信息
			printf("%s\r\n",RunTimeInfo);
		}
		Delay_Ms(10);
	}
}

2.4 获取任务运行时间

      (1)获取任务运行时间时需要提供时间基准,要设置相应的宏,在FreeRTOSconfig.h中

#define configGENERATE_RUN_TIME_STATS	   1     //为1时启用运行时间统计功能 
#define configUSE_STATS_FORMATTING_FUNCTIONS   1
#define configSUPPORT_DYNAMIC_ALLOCATION     1        //支持动态内存申请

      (2)提供相应时间基准函数,在timer.h中。
      设置时间基准函数用户只需要产生时基单元,设置好相关的宏,不需要用户调用。在设置时间基准需要保证该时间基准的频率高于FreeRTOS系统频率,要是系统频率的10~20倍。
      本示例的FreeRTOS系统频率为configTICK_RATE_HZ ( ( TickType_t ) 1000 ) ,也就是FreeRTOS系统时间为1ms,所以获取任务运行时间的时间基准为50us。

/*******用于给FreeRTOS计算任务运行时间提供时间基准*******/
volatile unsigned long long FreeRTOSRunTimeTicks;
void ConfigureTimeForRunTimeStas(void)//不需要用户调用,只需实现功能即可
{
	FreeRTOSRunTimeTicks=0;
	Tim1_Init(72,50);//初始化定时器1,周期50us,cnt+1时间为1us
}
void TIM1_UP_IRQHandler(void)
{
	if(TIM1->SR&1<<0)
	{
		FreeRTOSRunTimeTicks++;//运行时间统计基数计数器+1
	}
	TIM1->SR=0;//清除标志	
}

      (3)通过#define进行宏定义,给获取任务时间函数vTaskGetRunTimeStats()提供时间基准接口。在FreeRTOSconfig.h中。

//用于给获取任务函数提供时间基准
#defineportCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  ConfigureTimeForRunTimeStas() 
//用于提供当前时间基准变量 unsigned long long类型
#define portGET_RUN_TIME_COUNTER_VALUE()  FreeRTOSRunTimeTicks 

      获取任务运行时间

FreeRTOS

    2.5 获取指定任务信息

      获取指定任务信息需要设置宏configUSE_TRACE_FACILITY == 1,在FreeRTOSconfig.h中。

#define configUSE_TRACE_FACILITY	1       //为1启用可视化跟踪调试

      执行结果:

FreeRTOS

2.6 列表方式获取任务详细信息

      列表方式获取任务详细信息设置宏,FreeRTOSconfig.h中。

#define configUSE_TRACE_FACILITY	1       //为1启用可视化跟踪调试
#define configUSE_STATS_FORMATTING_FUNCTIONS	1 
#define configSUPPORT_DYNAMIC_ALLOCATION     1      //支持动态内存申请

      执行结果:

FreeRTOS

 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分