当我们在FreeRTOS执行多个任务的时候,每个任务使用的频率和重要性都有所差别,

比如我们想要保持云台平衡读取陀螺仪和加速度计到底数据就格外重要,所以读取数据的优先级一点更要高于启动任务,所以改变和查去优先级就格外重要

使用uxTaskPriorityGet来获得任务的优先级:

UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )

使用参数xTask来指定任务,设置为NULL表示获取自己的优先级。

使用vTaskPrioritySet 来设置任务的优先级:

void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )

使用参数xTask来指定任务,设置为NULL表示设置自己的优先级;

参数uxNewPriority表示新的优先级,取值范围是0~(configMAX_PRIORITIES – 1)。

在了解优先级后我们要对任务的状态进行了解

主要分为: 阻塞,暂停,就绪,运行

阻塞状态就是没有达到运行的条件,我个人把他简单理解成准备状态,准备的可以是时间也可以是时间,比如用vTaskDelay()就是主备多少时间,在阻塞状态下这个任务是不运行的,在满足条件后就会进入就绪状态,也就是由阻塞(准备)-》就绪

挂起状态:也由地方叫做暂停状态和阻塞有点相同,在暂停状态下的任务也不运行,但是暂停状态的启动是由自己控制的,

状态对比表

特性 阻塞状态(Blocked) 暂停状态(Suspended)
触发方式 任务自己调用等待函数 外部调用vTaskSuspend()
恢复方式 自动恢复(事件发生/超时) 外部恢复(需要调用vTaskResume()
使用场景 等待数据、信号量、时间 调试、临时停止、任务管理
状态转换 事件驱动,自动转换 需要显式控制
典型API函数 xQueueReceive()vTaskDelay()xSemaphoreTake() vTaskSuspend()vTaskResume()
内存占用 仍在内存中,等待队列中 仍在内存中,不在任何队列
调度器处理 仍在调度器管理中 完全移出调度器
优先级继承 可能发生 不发生

用这个函数vTaskSuspend可以让一个任务进入暂停状态

void vTaskSuspend( TaskHandle_t xTaskToSuspend )

用这个函数vTaskResume可以由暂停状态回复到,就绪状态

void vTaskResume( TaskHandle_t xTaskToResume )

就绪状态和运行状态就很好理解了,一个任务处于就绪状态的时,没当时间片轮到他,就会进入运行状态从而执行任务。

我们要想对一个工程操作自如我们就要,对任务的优先级和任务的状态精准控制

首先我们要知道的两点是:

1每一个相同优先级的任务事轮流执行的 2高优先级的任务先执行

所以

1 高优先级的任务进入就绪状态就会马上执行

2高优先级的任务没有执行完(不处于阻塞或者暂停状态)低优先级就不会执行

3如果高优先级由多个,也是轮流运行,也就是说一段时间内只会轮流执行同优先级的任务

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐