学习之路主要为FreeRTOS操作系统在STM32F103(STM32F103C8T6)上的运用,采用的是标准库编程的方式,使用的IDE为KEIL5。
注意!!!本学习之路可以通过购买STM32最小系统板以及部分配件的方式进行学习,也可以通过Proteus仿真的方式进行学习。
后续文章会同时发表在个人博客(jason1016.club)、CSDN;
视频会发布在bilibili(UID:399951374)
RTOS 系统的核心是任务管理,而任务管理的核心是任务切换,任务切换决定了任务的执行顺序,任务切换效率的高低也决定了一款系统的性能
一、什么时候执行任务切换(啥时候切换)
执行系统调用就是执行 FreeRTOS 系统提供的相关 API 函数,比如任务切换函数 taskYIELD(),FreeRTOS 有些 API 函数也会调用函数 taskYIELD(),这些 API 函数都会导致任务切换,这些 API 函数和任务切换函数 taskYIELD()都统称为系统调用。
FreeRTOS 中滴答定时器(SysTick)中断服务函数中也会进行任务切换
二、任务切换函数PendSV(怎么切换)
PendSV函数原理(优势)
将 PendSV 设置为最低的异常优先级,可以让 PendSV 异常处理在所有其他中断处理完成后执行,这对于上下文切换非常有用,也是各种 OS 设计中的关键。
因此,用PendSV作为任务切换函数的话,就把任务切换事件放在系统执行的最底层了,避免了任务切换会打断正在运行的中断事件这个问题
PendSV 异常将上下文切换请求延迟到所有其他 IRQ 处理都已经完成后,此时需要将 PendSV 设置为最低优先级。若 OS 需要执行上下文切换,他会设置 PendSV 的挂起壮态,并在 PendSV 异常内执行上下文切换
PendSV使用时机和方法(该切换时怎么切换)
-
- 在接收到上述系统调用的时候,通过SVC(中断控制和壮态寄存器 ICSR) 挂起PendSV,最后在空闲状态执行PendSV中执行任务切换操作
- 在接收到Systick中断后,由SVC(Systick)挂起PendSV,最后在空闲状态执行PendSV中执行任务切换操作
三、查找下一个要运行的任务(切换成什么?切换成某一优先级的任务列表)
通用方法
任务添加时会根据优先级大小赋值给就绪任务列表数组( pxReadyTasksLists[]),一个优先级一个列表,同优先级的就绪任务都挂到相对应的列表中。uxTopReadyPriority 代表处于就绪态的最高优先级值,系统按就绪态的最高优先级的高到低遍历,再依次执行对应的任务级列别,而针对同一优先级列表内的任务,则会按照次序依次执行。
硬件方法
硬件方法就是使用处理器自带的硬件指令来实现,原理与上述方法相似,不同点在于:使用硬件方法的时候 uxTopReadyPriority 就不代表处于就绪态的最高优先级了,而是使用每个 bit 代表一个优先级,bit0 代表优先级 0,bit31 就代表优先级 31,当某个优先级有就绪任务的话就将其对应的 bit 置 1。
四、时间片调度(同一优先级任务列表的任务切换)
这里提出一个问题,当有两个一样重要(优先级相等)的任务需要我们去执行的话,我们应该怎么处理?大家都知道即使移植了freertos的单片机同一时间也只能执行一个任务,当面对有个多个同等优先级的任务的情况,freertos给出的答案是时间片调度执行。
在 FreeRTOS 中允许一个任务运行一个时间片(一个时钟节拍的长度)后让出 CPU 的使用权,让拥有同优先级的下一个任务运行,FreeRTOS 中的这种调度方法就是时间片调度
这样的调度方式就好比我们平时看到的风扇叶面,一个页面代表一个同等优先级的任务,当我们执行得慢的时候,我们还能分清具体是那个叶面,而等风扇快速转动起来后我就分不清叶面的类型甚至页面的个数了。单片机同样如此当单片机以几十几百HZ运行,并且将时间片稀释得非常少的时候,我们就分不清他具体在执行什么任务了,乃至于我们会出现“单片机这几个任务是同时执行的错觉”,这也是为什么风扇转起来就像个圆的。这就是FreeRTOS处理多(同优先级)任务的方法。
本文为作者独立编写,本BLOG上所有的原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。