FreeRTOS任务调度启动流程
Preface
上一篇博客写了关于FreeRTos背景知识,有了基础的认识。
本篇博文正式开始讲诉FreeRTos源码
Preview
Attention
FreeRTos源码版本是V9.0.0
源码阅读工具:VS code
PS:在阅读源码的过程中需要注意以下三点
- 遇到没见过的函数,只需先知道该函数的函数名称,知道函数的功能,至于函数的具体实现我们可以先不了解
- 阅读源码的过程中会出现大量的条件编译,如果对某个宏定义的意思不了解那就不必要了解
- FreeRTos源码中有大量回调函数。这些回调函数一般需要用户编写并且需要在头文件中配置,阅读源码时不需要关注
Attention:
在阅读源码的过程中涉及到大量关于Cortex-M4架构相关的基础知识,但是我在该系列博客中是不会去讲解的,我会在ARM内核系列博客中会讲。之所以这么做就是因为按照这种方式才不会混乱。
FreeRTos目录结构
解释
如上图所示
- include文件夹中包含了FreeRTos使用到的头文件
- portable文件夹中包含了移值需要的内容,且内容的实现根据需要移值的芯片不同会有比较大的差异(本系列博文是基于Cortex-M4F)
- 剩下的源文件就是与硬件平台无关的FreeRTos的源代码
FreeRTos任务调度
一、vTaskStartScheduler函数中需要注意的细节
- Idle任务一定会被创建,只不过创建的方式会有所不同罢了
Idle任务到底是以静态的形式还是动态的形式取决于你自己
- 失能中断
可能很多人会有疑问,为什么这里需要失能中断。
因为在xPortStartScheduler()
中使能了Systick,而它会以一定的时间(操作系统的心脏)周期性的触发中断,为了避免在FreeRTos任务调度的启动过程中出现流程分叉,因此预先失能中断
-
初始化全局变量
我觉得在任务调度的启动流程中唯一有用的就是标记任务调度器处于运行状态!
二、xPortStartScheduler函数中需要注意的细节
- 启动系统滴答定时器
这个其实我觉得不用说,因为操作系统的运行肯定是要遵循一定的节拍,而这个节拍就是由系统滴答定时器来提供。
- 临界区变量初始化为0
这个我觉得它初始化为0的含义已经显而易见了
- 使能惰性压栈
使能惰性压栈的目的在于能够快速的响应中断。
三、prvStartFirstTask函数中需要注意的细节
- 恢复栈顶指针
在启动过程中调用到了若干个函数,调用函数就使用到了栈,因此在启动第一个任务之前,恢复默认的栈顶指针。
这里需要说明一下:
栈顶指针的值是在编译的时候就已经确定的,至于它存放在什么地方你可以去看下权威指南
- 使能中断
使能中断的目的是为了后面的触发 SVC中断做准备
四、vPortSVCHandler函数中需要注意的细节
该函数执行完之后就会开始处理第一个待执行的任务了。
这个函数就是ARM体系结构中的异常返回机制,ARM体系结构我打算在其它连载博客中讲诉。
总结
以上就是FreeRTos任务调度的启动流程,在该系列博客中但凡是和ARM内核相关的知识都不会讲太多,这个大家可以自己去看权威指南。