FreeRTOS应用之任务管理
何为任务
任务是一种在各自独立环境中无限循环的函数,即任务之间是相互独立的且有自己的工作环境。
任务执行一般采用抢占式方式,当任务处于不同优先级时采用抢占式方式执行,高优先级的任务可以打断低优先级的任务执行。当任务处于同一优先级时采用时间片轮转的方式执行。也可以都采用轮转的方式执行,但是不允许进行抢占。
任务调度器
任务调度器是基于抢占式制度进行任务调度的,但并非所有的程序都可以被抢占。 中断处理程序,调度器上锁程序,禁止中断程序都是不可被抢占的。
对于任务调度器来说,如何找到当前最高优先级的任务非常重要。
FreeRTOS系统采用两种方法查找最高优先级任务,一种通用方法:由于创建任务之后,任务优先级就确定了,直接在 就绪列表 (就绪列表按高低优先级排列)中查找。一种方法是计算前导零指令CLZ:类似于BitMap算法寻找最高优先级。
调度器理解:从宏观上来说采用了任务调度器之后,多个任务好像是同时执行,但是只有单个CPU不可能同时执行,只是因为任务之间切换频率很高,使多任务看起来同时执行。而任务调度器类似于裸机中while循环里的switch语句,switch依据不同的状态执行不同的语句,任务调度器依据不同的优先级执行不同的任务,且每个任务都是死循环。
任务状态
任务一般有四种状态。
状态 | 描述 |
---|---|
就绪 | 任务在就绪列表中等待调度器调用 |
运行 | 任务当前优先级最高被调度器调用 |
阻塞 | 任务由于挂起,延时,等待发生阻塞,从就序列表删除 |
挂起 | 任务对调度器来说不可见 |
任务状态迁移
任务相关函数
函数 | 描述 |
---|---|
vTaskSuspend() | 将指定任务挂起,不参与调度器调度 |
vTaskSuspendAll() | 将所有任务挂起,禁止调度器调度 |
vTaskResume() | 恢复指定任务 |
xTaskResumeAll() | 恢复所有任务 |
xTaskResumeFromISR() | 恢复指定任务,在中断中使用 |
vTaskDelete() | 删除任务 |
vTaskDelay() | 阻塞延时,相对延时 |
vTaskDelayUntil() | 阻塞延时,绝对延时 |
任务设计要点
1.任务设计时要存在阻塞,否则低优先级的任务无法得到执行。
2.中断程序优先级高于所有任务,因此中断程序执行时间要短,执行频率要低。
3.空闲任务不允许出现阻塞状态
4.任务设计时要考虑最大运行时间,实时响应指标,高优先级任务的运行时间不能大于低优先级任务的实时响应指标,否则低优先级任务无法满足实时响应指标。