---
title: rtos-freertos-04-任务的调试函数
EntryName: rtos-freertos-04-task-debug
date: 2020-06-22 08:49:06
categories:
tags:
- debug
- freertos
---

章节概述:

任务应用函数是一组辅助类函数,一般用于调试信息输出、获取任务句柄、获取任务状态、操作任务标签值等等。

概览

uxTaskPriorityGet():查询某个任务的优先级
vTaskPrioritySet():改变某个任务的任务优先级
uxTaskGetSystemState():获取系统中任务状态
vTaskGetInfo():获取某个任务信息
xTaskGetApplicationTaskTag():获取某个任务的标签(Tag)值
xTaskGetCurrentTaskHandle():获取当前正在运行的任务的任务句柄
xTaskGetHandle():根据任务名字查找某个任务的句柄
xTaskGetIdleTaskHandle():获取空闲任务的任务句柄
uxTaskGetStackHighWaterMark():获取任务的堆栈的历史剩余最小值,FreeRTOS 中叫做“高水位线”
eTaskGetState():获取某个任务的壮态,这个壮态是 eTaskState 类型
pcTaskGetName():获取某个任务的任务名字
xTaskGetTickCount():获取系统时间计数器值
xTaskGetTickCountFromISR():在中断服务函数中获取时间计数器值
xTaskGetSchedulerState():获取任务调度器的壮态,开启或未开启
uxTaskGetNumberOfTasks():获取当前系统中存在的任务数量
vTaskList():以一种表格的形式输出当前系统中所有任务的详细信息
vTaskGetRunTimeStats():获取每个任务的运行时间
vTaskSetApplicationTaskTag():设置任务标签(Tag)值
SetThreadLocalStoragePointer():设置线程本地存储指针
GetThreadLocalStoragePointer():获取线程本地存储指针

获取任务系统状态

UBaseType_t uxTaskGetSystemState(
TaskStatus_t * constpxTaskStatusArray,
const UBaseType_tuxArraySize,
unsigned long * constpulTotalRunTime );

描述:该函数向TaskStatus_t结构体填充相关信息,系统中每一个任务的信息都可以填充到TaskStatus_t结构体数组中,数组大小由uxArraySize指定。

在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必须设置为1,此函数才有效。

参数解析:

  • pxTaskStatusArray:指向TaskStatus_t类型的结构体数组。这个数组至少要包含1个元素。RTOS控制的任务数量可以使用API函数uxTaskGetNumberOfTasks()获取。
  • uxArraySize:参数pxTaskStatusArray指向的数组大小,也就是该数组的索引数目。
  • pulTotalRunTime:如果在文件FreeRTOSConfig.h中设置宏configGENERATE_RUN_TIME_STATS为1,则该函数将总运行时间写入*pulTotalRunTime中。pulTotalRunTime可以设置为NULL,表示忽略总运行时间。

返回值:被填充的TaskStatus_t结构体数量。这个值应该等于通过调用API函数uxTaskGetNumberOfTasks()返回的值,但如果传递给uxArraySize参数的值太小,则返回0。

注意:注意,这个函数仅用来调试用,调用此函数会挂起所有任务,直到函数最后才恢复挂起的任务,因此任务可能被挂起很长时间。

结构体TaskStatus_t定义如下:

typedef struct xTASK_STATUS
{
/* 任务句柄*/
TaskHandle_t xHandle; /* 指针,指向任务名*/
const signed char *pcTaskName; /* 任务ID,是一个独一无二的数字*/
UBaseType_t xTaskNumber; /* 任务当前的状态(运行、就绪、挂起等等)*/
eTaskState eCurrentState; /* 任务运行(或继承)的优先级。*/
UBaseType_t uxCurrentPriority; /* 当任务因继承而改变优先级时,该变量保存任务最初的优先级。仅当configUSE_MUTEXES定义为1有效。*/
UBaseType_t uxBasePriority; /* 分配给任务的总运行时间。仅当宏configGENERATE_RUN_TIME_STATS为1时有效。*/
unsigned long ulRunTimeCounter; /* 从任务创建起,堆栈剩余的最小数量,这个值越接近0,堆栈溢出的可能越大。 */
unsigned short usStackHighWaterMark;
}TaskStatus_t;

例子:

/*本例演示如是使用uxTaskGetSystemState()函数来获取运行时间信息,并将其转化为程序员更易识别的字符格式,这些转化后的字符保存到pcWriteBuffer中。*/
void vmyTaskGetRunTimeStats()
{
TaskStatus_t*pxTaskStatusArray;
volatileUBaseType_t uxArraySize, x;
unsignedlong ulTotalRunTime, ulStatsAsPercentage; /* 获取任务总数目*/
uxArraySize = uxTaskGetNumberOfTasks (); /*为每个任务的TaskStatus_t结构体分配内存,也可以静态的分配一个足够大的数组 */
pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t )); if(pxTaskStatusArray != NULL )
{
/*获取每个任务的状态信息 */
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray,
uxArraySize,
NULL);//&ulTotalRunTime ); /* 百分比计算 */
//ulTotalRunTime /= 100UL; /* 避免除零错误 */
if(1)//ulTotalRunTime > 0 )
{
/* 将获得的每一个任务状态信息部分的转化为程序员容易识别的字符串格式*/
for( x = 0; x < uxArraySize; x++ )
{
/* 计算任务运行时间与总运行时间的百分比。*/
//ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter /ulTotalRunTime; if(1) // ulStatsAsPercentage > 0UL )
{
sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n",
pxTaskStatusArray[ x ].pcTaskName,
pxTaskStatusArray[ x ].ulRunTimeCounter,
ulStatsAsPercentage );
}
else
{
/* 任务运行时间不足总运行时间的1%*/
sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n",
pxTaskStatusArray[ x ].pcTaskName,
pxTaskStatusArray[x ].ulRunTimeCounter );
}
}
} /* 释放之前申请的内存*/
vPortFree( pxTaskStatusArray );
}
}

获取当前任务句柄

TaskHandle_t xTaskGetCurrentTaskHandle(void );

描述:

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必须设置为1,此函数才有效。

参数解析:

返回值: 返回当前任务(调用该函数的任务)的句柄。

获取空闲任务句柄

TaskHandle_t xTaskGetIdleTaskHandle(void );

描述:

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetIdleTaskHandle必须设置为1,此函数才有效。

返回值:返回空闲任务句柄。空闲任务在RTOS调度器启动时自动创建。

获取任务堆栈最大使用深度

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );

描述:获取任务的堆栈的历史剩余最小值,FreeRTOS 中叫做“高水位线”。

任务的堆栈空间会随着任务执行以及中断处理而增长或缩小。该函数可以返回任务启动后的最小剩余堆栈空间。换句话说,可以间接估算出一个任务最多需要多少堆栈空间。

在文件FreeRTOSConfig.h中,宏INCLUDE_uxTaskGetStackHighWaterMark 必须设置成1,此函数才有效。

参数解析:

xTask:任务句柄。NULL表示查看当前任务的堆栈使用情况。

返回值:返回最小剩余堆栈空间,以字为单位。比如一个32为架构处理器,返回值为1表示有4字节堆栈空间没有使用过。如果返回值为0,则任务很可能已经发生了堆栈溢出。

例子:

void vTask1( void * pvParameters )
{
UBaseType_t uxHighWaterMark; /* 入口处检测一次 */
uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL ); for( ;; )
{
/* 正常调用函数 */
vTaskDelay( 1000 ); /* 测量堆栈使用情况 */
uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL );
}
}

获取任务状态

eTaskState eTaskGetState( TaskHandle_txTask );

描述:返回一个枚举类型的任务状态值。

在文件FreeRTOSConfig.h中,宏INCLUDE_eTaskGetState必须设置为1,此函数才有效。

参数解析:

xTask:任务句柄

返回值:

返回值 状态
eReady 就绪
eRunning 运行
eBlocked 阻塞
eSuspended 挂起
eDeleted 删除

获取任务描述内容

char * pcTaskGetTaskName( TaskHandle_txTaskToQuery );

描述:获取任务的名称。

在文件FreeRTOSConfig.h中,宏INCLUDE_pcTaskGetTaskName必须设置成1,此函数才有效。

参数解析:xTaskToQuery:任务的句柄。NULL表示获取当前任务的描述内容指针。

返回值:一个指针,指向任务名称字符串。

获取系统节拍次数

volatile TickType_t xTaskGetTickCount(void );

描述:

这个函数不能在ISR中调用;用volatile TickType_t xTaskGetTickCountFromISR( void )代替

返回值:返回从vTaskStartScheduler函数调用后的系统时钟节拍次数。

获取调度器状态

BaseType_t xTaskGetSchedulerState( void);

描述:获取调度器当前状态。

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetSchedulerState或configUSE_TIMERS必须定义为1,此函数才有效。

返回值:返回值是以下常量之一(定义在task.h)

  • taskSCHEDULER_NOT_STARTED(未启动)
  • taskSCHEDULER_RUNNING(正常运行)
  • taskSCHEDULER_SUSPENDED(挂起)

获取任务总数

UBaseType_t uxTaskGetNumberOfTasks(void );

描述:获取RTOS内核当前管理的任务总数。

返回值: 返回RTOS内核当前管理的任务总数。

包含所有就绪、阻塞和挂起状态的任务。对于一个删除的任务,如果它的堆栈空间还没有被空闲任务释放掉,则这个被删除的任务也含在计数值中。

获取所有任务详情

void vTaskList( char *pcWriteBuffer );

描述:将每个任务的状态、堆栈使用情况等以字符的形式保存到参数pcWriteBuffer指向的区域。vTaskList()函数调用usTaskGetSystemState()函数,然后将得到的信息格式化为程序员易读的字符形式。输出的内容例子如下图所示,图中State一栏中,B表示阻塞、R表示就绪、D表示删除(等待清除内存)、S表示挂起或阻塞。

在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS必须定义为1,此函数才有效。

参数解析:保存信息的缓冲区(格式为ASCII);要足够大,以容纳生成的报告,每个任务大约需要40个字节。

注意:调用这个函数会挂起所有任务,这一过程可能持续较长时间,因此本函数仅在调试时使用。

获取任务运行时间

void vTaskGetRunTimeStats( char*pcWriteBuffer );

描述:用于统计每个任务的运行时间。

参数解析:保存任务的运行时间信息(格式为ASCII);要足够大,以容纳生成的报告,每个任务大约需要40个字节。

注意:调用这个函数会挂起所有任务,这一过程可能持续较长时间,因此本函数仅在调试时使用。

要使用这个函数必须满足一些条件,那就是必须有一个用于时间统计的定时器或计数器,这个定时器或计数器的精度要至少大于10倍的系统节拍周期。

这个定时器或计数器的配置以及获取定时时间是由两个宏定义实现的,这两个宏一般在文件FreeRTOSConfig.h中定义。

  • 配置定时器或计数器的宏为portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),
  • 获取定时时间的宏为portGET_RUN_TIME_COUNTER_VALUE。

必须在文件FreeRTOSConfig.h中将宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS设置为1,此API函数才有效。

例子:

char RunTimeInfo[400];      //保存任务运行时间信息

//FreeRTOS时间统计所用的节拍计数器
volatile unsigned long long FreeRTOSRunTimeTicks; //初始化TIM3使其为FreeRTOS的时间统计提供时基
void vConfigureTimeForRunTimeStats(void)
{
//定时器3初始化,定时器时钟为72M,分频系数为72-1,所以定时器3的频率
//为72M/72=1M,自动重装载为50-1,那么定时器周期就是50us
FreeRTOSRunTimeTicks = 0;
TIM3_Int_Init(50-1,72-1); //初始化TIM3,包括对应的中断代码
} unsigned long long getRunTimeCounterValue(void)
{
return FreeRTOSRunTimeTicks;
} void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
FreeRTOSRunTimeTicks++;
}
} void RunTimeStats_task(void *pvParameters)
{
while(1)
{
{
memset(RunTimeInfo,0,400); //信息缓冲区清零
vTaskGetRunTimeStats(RunTimeInfo); //获取任务运行时间信息
printf("任务名\t\t\t运行时间\t运行所占百分比\r\n");
printf("%s\r\n",RunTimeInfo);
}
vTaskDelay(2000);
}
}

在文件FreeRTOSConfig.h中,定义下列代码:

extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() getRunTimeCounterValue()

Freertos学习:04-任务的调试函数的更多相关文章

  1. 【FreeRTOS学习04】小白都能懂的 Queue Management 消息队列使用详解

    消息队列作为任务间同步扮演着必不可少的角色: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 xQUEUE 3 相关概念 3 ...

  2. Python学习--04条件控制与循环结构

    Python学习--04条件控制与循环结构 条件控制 在Python程序中,用if语句实现条件控制. 语法格式: if <条件判断1>: <执行1> elif <条件判断 ...

  3. JavaScript学习04 对象

    JavaScript学习04 对象 默认对象 日期对象Date, 格式:日期对象名称=new Date([日期参数]) 日期参数: 1.省略(最常用): 2.英文-数值格式:月 日,公元年 [时:分: ...

  4. Thinkphp学习04

    原文:Thinkphp学习04 一.ThinkPHP 3 的输出      (重点) a.通过 echo 等PHP原生的输出方式在页面中输出 b.通过display方法输出   想分配变量可以使用as ...

  5. 【FreeRTOS学习06】深度解剖中断与任务之间同步的具体使用场景

    嵌入式系统中中断是必不可少的一部分: [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 1 前言 2 中断特点 3 延迟中断处理 3.1 信号量的使用 3.2 ...

  6. 【FreeRTOS学习05】深度解剖FreeRTOSConfig.h实现对系统的自定义剪裁

    ROM/RAM太小,因此要对系统进行剪裁: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 系统的剪裁 2 FreeRTOSConfi ...

  7. FreeRTOS学习笔记——FreeRTOS 任务基础知识

    RTOS 系统的核心就是任务管理,FreeRTOS 也不例外,而且大多数学习RTOS 系统的工程师或者学生主要就是为了使用RTOS 的多任务处理功能,初步上手RTOS 系统首先必须掌握的也是任务的创建 ...

  8. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. Java虚拟机JVM学习04 类的初始化

    Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...

  10. Android学习系列(37)--App调试内存泄露之Context篇(下)

    接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ...

随机推荐

  1. SpringBoot配置两个一样的Bean,区分两个配置类——@Primary

    1.@Primary 作用: 指定默认bean. 当没有根据名字显示要注入哪个bean的时候,默认使用打了@Primary标签的bean 2.配置两个一样的bean @Configuration pu ...

  2. 引爆你的网页乐趣!前端十个令人捧腹的JavaScript整蛊代码。

    愚人节整蛊代码.想要在网页上增添一抹幽默与惊喜吗?或是想给你的朋友一个意想不到的"小惊喜"?那么,这十款简单而有趣的JavaScript前端整蛊代码绝对能满足你的需求!每一个代码都 ...

  3. 【zabbix】snmp监控linux主机

    1.安装net-snmp # yum install -y net-snmp 2.配置文件 /etc/snmp/snmpd.conf 添加如下内容 view systemview included . ...

  4. leaflet 基本案例-图层控件:基础图层+业务图层

    可执行示例一个,如下: <!DOCTYPE html> <html> <head> <title>Layers Control Tutorial - L ...

  5. Java 工程文件的 .gitignore

    以下是一个排查 Java 工程文件的 .gitignore 文件示例: # Java 编译器生成的文件 *.class # Maven 生成的文件夹 target/ # Eclipse 生成的文件夹 ...

  6. C语言:如何实现在txt文件中删除超链接、统计单词数量、生成单词列表 (文本流操作并解决乱码)

    1.首先读取原文件内容文本流(包含中英文) 2.删除超链接 3.统计单词数量 4.去除重复单词 读取文件需要自己在文本笔记中保存一个网页,保存为txt文件 注意的是,在这个代码实现过程中,我学到的是如 ...

  7. Intel HDSLB 高性能四层负载均衡器 — 快速入门和应用场景

    目录 目录 目录 前言与背景 传统 LB 技术的局限性 HDSLB 的特点和优势 HDSLB 的性能参数 基准性能数据 对标竞品 HDSLB 的应用场景 HDSLB 的发展前景 参考文档 前言与背景 ...

  8. 【Azure Developer】如何通过Azure Portal快速获取到对应操作的API并转换为Python代码

    问题描述 对于Azure资源进行配置操作,门户上可以正常操作.但是想通过Python代码实现,这样可以批量处理.那么在没有SDK的情况下,是否有快速办法呢? 问题解答 当然可以,Azure Porta ...

  9. Vue Vue-Router params 传参 为空 path定义参数 参数 param is not repeatable

    我在Vue-Router4.0.3版本上出现这个问题 因为官方 在2022年8月22日时废除了未定义的传参方式,所以必须使用定义的params. 解决办法: 在配置路由时:path路径上带上传值的ke ...

  10. Anaconda 虚拟环境

    1. 查看虚拟环境 conda env list 2. 创建虚拟环境 conda create -n env_name python=3.8 --- env_name: 虚拟环境名 --- pytho ...