0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-06-08 09:12 次阅读

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 

获取任务运行时间

pYYBAGKXDs6ADoxkAABt65t6uA0899.png

2.5 获取指定任务信息

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

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

执行结果:

pYYBAGKXD0GAasBxAAArvYnoq50322.png

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

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

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

执行结果:

pYYBAGKXD42AH4zYAAAUVxt7oEw075.png

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

    关注

    37

    文章

    6801

    浏览量

    123283
  • STM32
    +关注

    关注

    2270

    文章

    10895

    浏览量

    355729
  • FreeRTOS
    +关注

    关注

    12

    文章

    484

    浏览量

    62139
收藏 人收藏

    评论

    相关推荐

    FreeRTOS嵌入式实时操作系统

      1 FreeRTOS操作系统功能   作为一个轻量级的操作系统FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、
    发表于 07-06 11:07 6586次阅读
    <b class='flag-5'>FreeRTOS</b>嵌入式<b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>

    实时操作系统FreeRTOS移植教程

    Free 即免费的,RTOS 全称是 Real Time Operating System,中文就是实时操作系统。注意,RTOS 不是指某一个确定的系统,而是指一类系统。比如 uC/O
    的头像 发表于 06-08 09:23 8651次阅读
    <b class='flag-5'>实时</b><b class='flag-5'>操作系统</b><b class='flag-5'>FreeRTOS</b>移植教程

    【案例分享】FreeRTOS的嵌入式实时操作系统的实现

    FreeRTOS是一个源码公开的免费的嵌入式实时操作系统,通过研究其内核可以更好地理解嵌入式操作系统的实现原理.本文主要阐述FreeRTOS
    发表于 07-23 04:30

    请问freertos是硬实时操作系统吗?

    freertos是硬实时操作系统吗?都有哪些硬实时操作系统啊?
    发表于 06-13 09:00

    FreeRTOS实时操作系统

    FreeRTOS实时操作系统,Nabto正在努力建立一个强大的FreeRTOS + Nabto组合的解决方案。我们最新推出AppMyProduct应用平台可帮助您快速开发远程控制设备
    发表于 08-04 07:58

    实时任务操作系统(RTOS)

    任务、进程和线程。实时任务操作系统(RTOS)是嵌入式应用软件的基础和开发平台,它是根据操作系统的工作特性
    发表于 08-24 06:34

    为什么要在单片机中使用实时任务操作系统

    为什么要在单片机中使用实时任务操作系统该视频在113分10秒之后,讲了实时操作系统的使用价值。老师讲得非常好,我就不过多赘述了。(这个视频
    发表于 08-24 06:02

    嵌入式实时操作系统FreeRTOS基本概述

    嵌入式实时操作系统FreeRTOS基本概述在嵌入式领域当中,实时操作系统的应用越来越广泛了,目前嵌入式
    发表于 02-16 07:12

    基于FreeRTOS的嵌入式实时操作系统的原理和实现

    FreeRTOS是一个源码公开的免费的嵌入式实时操作系统,通过研究其内核可以更好地理解嵌入式操作系统的实现原理.本文主要阐述FreeRTOS
    发表于 11-18 03:34 6669次阅读

    什么是操作系统?FreeRTOS中文实用教程让你快速入门FreeRTOS

    本文档的主要内容详细介绍的是什么是操作系统?FreeRTOS中文实用教程让你快速入门FreeRTOS带你了解了1.认识操作系统 2.轻松上手RTOS 3.
    发表于 09-12 16:51 276次下载
    什么是<b class='flag-5'>操作系统</b>?<b class='flag-5'>FreeRTOS</b>中文实用教程让你快速入门<b class='flag-5'>FreeRTOS</b>

    嵌入式实时操作系统FreeRTOS在ARM7上移植实现

    嵌入式实时操作系统FreeRTOS在ARM7上移植实现(嵌入式开发工程师待遇)-嵌入式实时操作系统Fre
    发表于 07-30 12:05 21次下载
    嵌入式<b class='flag-5'>实时</b><b class='flag-5'>操作系统</b><b class='flag-5'>FreeRTOS</b>在ARM7上移植实现

    STM32-初学FreeRTOS操作系统

    freeRTOS实时操作系统之一,特点是多线程,采用“轮换”的方式实现“并行”的效果,操作系统内可以建立任务,每个
    发表于 12-08 14:21 14次下载
    STM32-初学<b class='flag-5'>FreeRTOS</b><b class='flag-5'>操作系统</b>

    FreeRTOS:一个迷你的实时操作系统内核

    ** 1、FreeRTOS** FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:
    的头像 发表于 06-29 17:15 988次阅读
    <b class='flag-5'>FreeRTOS</b>:一个迷你的<b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>内核

    FreeRTOS实时操作系统简述

    FreeRTOS是一个为嵌入式系统设计的开源实时操作系统。它提供了一个多任务内核和一系列组件功能,适合在资源受限的设备上管理
    发表于 09-19 12:37 1795次阅读
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>简述

    实时操作系统之RT-Thread及FreeRTOS

    RT-Thread与其他很多RTOS如FreeRTOS的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件,如下图所示。FreeRTOS和RT-Thread是两种常见的嵌入式实时
    的头像 发表于 05-29 08:10 3846次阅读
    <b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>之RT-Thread及<b class='flag-5'>FreeRTOS</b>