RTOS任务状态总结及查看 RTOS 任务的状态

概述

任务状态小节

前述已经学习了 FreeRTOS 的任务的创建、延时、挂起、任务通知的相关知识。本小节对任务的状态进行总结,并给出使用标准的 API 查询系统中所有任务状态的方法。这不仅对加深我们对 Task 的理解有重要意义,也是系统出现问题时,查询系统bug的重要方法。

当前,相关的文档将 RTOS 中的任务状态分为五种:

  1. 运行状态:当前正在执行的任务的状态,只可能会一个当前正在执行的任务。初运行态外,下述的情况都可以归类到 非运行 态。
  2. 就绪状态:随时可以运行的任务的状态,就绪状态的任务随时等待任务调度器调度,是在被任务调度器赋予 CPU 使用权之前的状态。刚创建的任务立即进入就绪状态,比如系统中正在运行优先级为 2 的任务,优先级为1 的任务因为优先级低而未进入运行状态时,就处于就绪状态。
  3. 阻塞状态:任务因为某些原因暂时不能被任务调度器赋予 CPU 使用权状态。一般情况下正在等待某些事件的发生比如调用了 xTaskNotifyWait() 等待任务通知的任务,或者等待延时时间结束的事件比如调用了 xTaskDelay() 的任务,在一段时间内任务会被阻塞,在这些事件达成后任务会自动回到就绪状态。
  4. 挂起状态:vTaskSuspend()函数会让任务进入挂起状态,这时候这个任务不会执行。调用xTaskResume()函数才能让这些任务回到就绪状态
  5. 删除状态:一个任务被使用vTaskDelete()函数后被删除,处于删除状态。

我在RTOS 任务状态总结中将 RTOS 的系统状态分为五种:未创建态、就绪态、运行态、挂起态、延时态五种状态。将阻塞(因延时而阻塞、因等待通知而阻塞)的两种情况划分为延时态。其实大致意思是相同的,大家按照最好理解的方式理解记忆就可以了。

在这里插入图片描述
典型的让任务进入几种状态的方法是:

APIStatus
xTaskCreate()调用后进入就绪态
xTaskDelay()调用后进入阻塞态,等待计时结束
xTaskNotifyWait()调用后进入阻塞态,等待任务通知
vTaskSuspend()调用后进入挂起态,需使用 xTaskResume() 才能解除挂起
vTaskDelete()调用后进入删除态

细心的读者可能已经发现了,没有 API 可以让 任务进入运行态,这是因为任务是否进入运行态,是调度器自动进行管理的,关于调度器的基本介绍,读者可回顾RTOS 中的任务调度与三种任务模型

使用 API 查询任务的状态

1)可以通过 vTaskGetInfo()获取某个任务当前的信息:

void vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState)

该函数将任务的信息写到 TaskStatus 类型的变量中,该变量包含了任务的所有信息:

typedef struct xTASK_STATUS
{
    TaskHandle_t xHandle;                            /* The handle of the task to which the rest of the information in the structure relates. */
    const char * pcTaskName;                         /* A pointer to the task's name.  This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
    UBaseType_t xTaskNumber;                         /* A number unique to the task. */
    eTaskState eCurrentState;                        /* The state in which the task existed when the structure was populated. */
    UBaseType_t uxCurrentPriority;                   /* The priority at which the task was running (may be inherited) when the structure was populated. */
    UBaseType_t uxBasePriority;                      /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex.  Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
    uint32_t ulRunTimeCounter;                       /* The total run time allocated to the task so far, as defined by the run time stats clock.  See https://www.FreeRTOS.org/rtos-run-time-stats.html.  Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
    StackType_t * pxStackBase;                       /* Points to the lowest address of the task's stack area. */
    configSTACK_DEPTH_TYPE usStackHighWaterMark;     /* The minimum amount of stack space that has remained for the task since the task was created.  The closer this value is to zero the closer the task has come to overflowing its stack. */
#if configTASKLIST_INCLUDE_COREID
    BaseType_t xCoreID;                              /*!< Core this task is pinned to (0, 1, or -1 for tskNO_AFFINITY). This field is present if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID is set. */
#endif
} TaskStatus_t;

2)相比 vTaskGetInfo()vTaskList()可以获取当前系统中所有任务的状态信息。

void vTaskList(char *pcWriteBuffer)

需求及功能解析

示例通过函数打印当前系统中各个任务的状态。

示例解析

示例中通过上述介绍的函数打印当前系统中各任务的状态,相关 log:

This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295172 bytes
TASK3: task3_flag = 0

app_main task status: xTaskNumber=4 eCurrentState=0 uxCurrentPriority=1
Task Name       Status  Prio    HWM     Task#   Affinity
task4           X       24      1296    10      -1
main            R       1       2368    4       0
IDLE            R       0       1068    6       1
IDLE            R       0       1108    5       0
task3           B       22      472     9       -1
esp_timer       S       22      3656    3       0
ipc1            B       24      1116    2       1
task2           S       23      1600    8       -1
task1           S       24      1656    7       -1
ipc0            B       24      1076    1       0
Task Name       Status  Prio    HWM     Task#   Affinity
task4           X       24      768     10      -1
IDLE            R       0       1068    6       1
IDLE            R       0       1108    5       0
task3           B       22      472     9       -1
ipc1            B       24      1116    2       1
task2           S       23      1600    8       -1
task1           S       24      1656    7       -1
ipc0            B       24      1076    1       0
esp_timer       S       22      3656    3       0

以上 log 打印了一次 main task 的相关信息,即 main task 的任务序号为4,执行该打印时的状态为X(正在执行),优先级为1。不了解这个 main task 的可以参考该博客

以上 log 打印了两次 系统中所有任务 的状态。包括、任务的运行状态(Status)、优先级(Prio)、高水位线(HWM)、任务序号(Task#,通常是任务被创建的顺序)、CPU核心(Affinity)。

其中任务状态中相关的字母略缩写含义为:blocked (‘B’), ready (‘R’), deleted (‘D’),suspended (‘S’),Execute(X).

讨论

  1. 负责打印 Task Status 的 任务的优先级该如何安排?
  2. 注意,使用 vTaskGetInfo() 时,传入该函数的 task_list_buffer 数组是没有检查大小的,通常按照每个任务 40bytes 的大小,来存储任务的统计信息,如果没有分配正确的大小,那容易数组越界,导致程序出现无法预知的错误。更多情况下,其实推荐使用更安全的 uxTaskGetSystemState() 来统计这些信息,这点可以参考 RTOS 系统篇-统计任务的 CPU 使用率

总结

1)任务可以分为几种状态:运行态、非运行态(包括就绪、阻塞(等待延时结束的阻塞和等待事件到来的阻塞)、挂起、删除)。

2)查看任务的状态可以使用函数:vTaskGetInfo()vTaskList()

作为入门,当前对 RTOS 中任务的相关介绍先写到这里,后续待介绍完更多的基础知识,将通过 任务-高级篇 介绍更多 RTOS 任务使用的知识和方法。

资源链接

1)Learning-FreeRTOS-with-esp32 系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)

3)下一篇:RTOS 任务同步与消息通信篇概述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RTOS任务的优先级可以根据任务的重要性和紧急程度来确定。一般来说,优先级较高的任务会在优先级较低的任务之前执行。在FreeRTOS中,任务的优先级是通过一个整数值来表示的,数值越小表示优先级越高。任务的优先级可以在任务创建时指定,也可以在运行时动态改变。 确定任务的优先级时,需要考虑以下几个因素: 1. 任务的功能和重要性:根据任务的功能和对系统的贡献程度,可以给予较高的优先级。例如,对于实时性要求较高的任务,可以给予较高的优先级。 2. 任务的依赖关系:如果一个任务依赖于另一个任务的结果或资源,那么它的优先级应该高于被依赖任务的优先级,以确保依赖任务能够及时完成。 3. 任务的执行时间:如果一个任务需要较长的执行时间,那么它的优先级应该较低,以避免饥饿其他任务的执行时间。 在确定任务的优先级时,还需要考虑任务间的相互作用和竞争条件。例如,如果一个任务持有一个共享资源的锁,那么其他需要访问该资源的任务的优先级应该高于持有锁的任务,以避免资源竞争和死锁的发生。 总之,确定RTOS任务的优先级需要综合考虑任务的功能、重要性、依赖关系和执行时间等因素,以确保系统的实时性和稳定性。 #### 引用[.reference_title] - *1* *3* [RTOS介绍------一、任务状态,优先级,调度](https://blog.csdn.net/cesare20/article/details/122526113)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [嵌入式技术栈之RTOS的优先级翻转问题](https://blog.csdn.net/dop102/article/details/124121357)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网老王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值