嵌入式开发学习日志50——任务调度与状态

在前面提到,如果只是创建任务的话任务是执行不起来的,需要将其放入任务调度器中供系统调度,这样才能保证任务的执行,而任务调度的关键就在于vTaskStartScheduler()函数。

要注意的是,FreeRTOS中系统每时每刻都需要运行一个任务,这时空闲任务就显得必不可少了。空闲任务不可以被挂起或者删除,同时优先级也是所有任务中最低的,以防和其它任务抢CPU的使用权。当然,FreeRTOS贴心的帮各位实现了,不需要花费额外的精力自己去创一个。

在启动任务的过程中,不同的硬件架构会导致函数的代码改变。这里以ARM Cortex-M系列处理器为例(另外两个分别是A系列和R系列,这两个系列分别面向了更高端的应用,而M系列面向低端应用,尤其是那些对成本和功耗都比较敏感的应用)。在Cortex-M3中,任务启动与切换分别用到了SVC、PendSV、SysTick。

SVC被称为系统服务调用,用于任务的启动,部分操作系统只允许用户间接访问硬件,此时就需要通过SVC向系统服务函数发出呼叫,系统的SVC异常服务例程执行后,完成用户的呼叫请求。

PendSV成为可挂起系统调用,用于任务的切换,它可以被挂起,当高优先级中断运行时,PendSV会延迟执行,直到高优先级中断运行完毕。

SysTick用于产生时钟,提供时间片,多任务的优先级相同时,可以让SysTick中断,将时间片交给下一个任务。

不难看出,调度器是一个基于优先级的全抢占式调度。当然,凡事总有例外,中断处理函数、调度器锁定的代码以及禁止中断的代码是无法抢占的。

细心的读者应该也发现了,我在前面几次提到过挂起这个词,其实这就是任务的状态之一,之前提到的任务就绪也属于任务状态的范畴。

任务状态总共分为四种,就绪、运行、挂起、阻塞,每个任务都是在这四个状态中循环往复的。

就绪就是任务具备执行能力,随时可以被调度器调度,此时任务处于就绪列表中。

运行就是任务正在占用处理器。

阻塞状态比较特殊,此时任务在等待时序或者外部中断,此时的任务虽然不处于就绪列表中,但是仍然可以被调度器看见。

挂起与阻塞不同,挂起的任务就消失在了调度器的视野里,一般这种任务是较长时间不会执行的任务,但是总有什么时候会用到。

任务状态之间的切换规律如下:任务在初次创建完成后就进入就绪列表,处于就绪状态,等待任务调度器调度;任务切换后,该优先级的任务开始执行,此时处于运行状态;当有更高优先级的任务就绪时,该任务会被打断并重新进入就绪列表中排队。若是该任务遇到了时延,则会进入阻塞状态,此时就绪列表中就不会有该任务,直到阻塞恢复,再重新进入就序列表。上述的任何一种状态的任务都有可能被挂起,此时只需要调用vTaskSuspend()函数即可。

相关推荐
xqqxqxxq9 小时前
树结构技术学习笔记
数据结构·笔记·学习
今天的你比昨天进步了?9 小时前
单片机程序,keil可以正常编译,VScode编译报错处理
vscode·单片机·嵌入式硬件
linbaiwan6669 小时前
42V/50V/60V高耐压OVP保护芯片的应用——PW1600实测70V耐压
嵌入式硬件
嵌入式小站9 小时前
STM32 零基础可移植教程 24:SPI Flash 读数据,先从指定地址读几个字节
chrome·stm32·嵌入式硬件
十月的皮皮10 小时前
C语言学习笔记202606008- 三角形判断(3种方法)
c语言·笔记·学习
XGeFei10 小时前
【Fastapi学习笔记(6)】—— Fastapi文件上传、请求头自动转换
笔记·学习·fastapi
一口吃俩胖子10 小时前
【脉宽调制DCDC功率变换学习笔记024】频域性能
笔记·学习
吃着火锅x唱着歌10 小时前
深度探索C++对象模型 学习笔记 第五章 构造、解构、拷贝语意学(2)
c++·笔记·学习
中小企业实战军师刘孙亮10 小时前
快消纺织五金怎么融合?三大业态协同发展战略思路-佛山鼎策创局破局增长咨询
学习·面试·创业创新·制造·学习方法
Upsy-Daisy10 小时前
Hermes Agent 学习笔记 04:工具调用系统,让 Agent 从“会说”变成“会做”
java·笔记·学习