全部学习汇总: GreyZhang/g_FreeRTOS: learning notes about FreeRTOS. (github.com)
继续前面调度器启动最后面没有分析完的几个接口,现在还剩下一个任务上下文切换还有一个错误处理。这一次,分析一下上下文切换的实现。
其实,从这部分注释看,这个接口在这里应该是运行不到的。在这里增加了一下也不过是防御性的编程设计而已。那么,接下来看看这个上下文切换的接口在整个OS中的使用情况。
从调度方面看,第一个头文件其实可以不去分析了。另外需要看的还有两个文件,先看port.c的部分。
port.c里面的3个部分,其中2个前面的截图中已经出现了。一个是注释,另一个其实是不需要关注的。唯一有吊用的其实是这里,也就是PendSV的处理程序。这个接口的具体实现有很多汇编,应该是硬件相关度很高的,后面再做分析。
再看task.c,这里面其实也只有一个地方调度,那就是vTaskSuspend()接口中在使用。另外一处其实是这个接口的实现部分。这样,上下文切换的条件其实就很明确了,当有任务挂起的操作或者是出现了PendSV的时候,会触发任务上下文切换的操作。接下来,分析下这个接口的实现。
首先,接口先判断了调度器的挂起状态,如果不是pdFALSE,那么给下面的状态量进行赋值,设置为TRUE。
关于上面的状态的理解,我参考了代码中的另一段注释。这个量应该是用来标记是否需要进行上下文切换的。因此,上面的判断实现的逻辑是:如果调度器没有挂起,那么执行上下文切换。
这里的uxSchedulerSuspended应该是用来标记任务调度器挂起请求次数的,写操作看起来只有这两个地方存在。
如果任务调度器已经挂起了,那么标记不进行上下文切换动作。否则,标记上下文切换标志之后执行任务运行时间的统计。
之后,这里有效的操作就是选择一个最高优先级的任务来执行。
这样,上下文切换的总结一下上下文切换需要做的事情:如果调度器挂起了,那么设置一个标志信息提示有一个任务切换的等待。如果没有挂起,那么就选择一个高优先级的任务执行。当配置了时间统计、堆栈检查等功能的时候,相应的功能也是在这里处理。