文章目录
1、tick中断——RTOS的时钟基准
(1)tick中断是任务切换的基础,在里面会判断是否需要切换任务
其有一个定时器中断,每1ms(这个时间可以自己设定,具体设置处如下图)进入一次,同时tick count加1
tick count初始值为0,使用xTaskGetTickCount这个函数可以获取其值,在任务中可以通过tick count来自定义任务进入的状态。
(2)tick中断处理的事情有:找出优先级最高的任务并且执行这个任务
如何找出优先级最高的任务?
到链表中查找,对于FreeRTOS来说,其有三大类链表,分别是就绪链表(Ready List,其又根据优先级等级每个等级设置一个链表),阻塞链表(Delay List)和挂起链表(Suspend List)
对于任务来说,其状态发送改变的同时,会对任务本身挂载的链表进行更新。如:当任务发生阻塞的时候,会同时立即更新任务的状态链表。
2、任务管理
(1)任务调度算法/策略
从系统的角度来看,任务是竞争系统资源的最小运行单元。
在任何时刻,只有一个任务得到运行,每个任务都在自己的环境中运行,而这个运行的任务由FreeRTOS的调度器决定。
FreeRTOS 中的任务是抢占式调度机制,高优先级的任务可打断低优先级正在运行任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。
同时 FreeRTOS 也支持时间片轮转调度方式,只不过时间片的调度是不允许抢占任务的 CPU 使用权。即在任务同等优先级的基础上,决定各个任务是否交替执行(即每个任务执行一个tick)
具体配置如下图:
需要注意的是:在设置不抢占时永远会礼让;在设置不抢占时连轮流执行(支持时间片)的机会都没有了。
(2)任务调度器
任务调度原则:
一旦任务状态发生了改变,并且当前运行的任务优先级小于优先级就绪队列组中任务最高优先级时,立刻进行任务切换(除非当前系统处于中断处理程序中或禁止任务切换的状态)。
1)全抢占式调度
FreeRTOS 中提供的任务调度器是基于优先级的全抢占式调度:在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的。
当有比当前任务优先级更高的任务就绪时,当前任务将立刻被换出,高优先级的任务抢占处理器运行。
2)FreeRTOS内核中寻找最高优先级任务的两种方法
(1)在就绪链表中查找从高优先级往低查找 uxTopPriority,因为在创建任务的时候已经将优先级进行排序,查找到的第一个 uxTopPriority 就是我们需要的任务,然后通过 uxTopPriority 获取对应的任务控制块。
(2)利用计算前导零指令 CLZ,直接在uxTopReadyPriority 这个 32 位的变量中直接得出 uxTopPriority,这样子就知道哪一个优先级任务能够运行,这种调度算法比普通方法更快捷,但受限于平台。
FreeRTOS 内核中相同优先级的任务采用时间片轮转方式进行调度(也就是通常说的分时调度器),时间片轮转调度仅在当前系统中无更高优先级就绪任务存在的情况下才有效。