freeRTOS
支持多个任务具有相同的优先级,因此,当它被配置为可抢占内核时,调度算法既支持基于优先级的调度,也支持时间片轮流调度。任何时候调度器运行时它都选择处于就绪状态下的优先级最高的那个任务;如果有多个任务处于同一优先级,则freertos每个时钟节拍的中断服务程序中,将对这些任务应用换调度算法,轮流执行这些任务。
系统用uxTopReadyPriority全局变量记录当前处于就绪态的任务的最高优先级。调度的时候就根据这个uxTopReadyPriority直接找到就绪链表中pxReadyTasksLists[ uxTopReadyPriority ]的任务,进行运行。
一个任务可以通过调用 taskYIELD() 让出cpu,从而调度令一个任务运行。它的实现如下:
#define taskYIELD() portYIELD()
而portYIELD()是一个体系结构相关的函数,对于不同的mcu需要实现这么一个函数完成调度。我拿atmel的atmega323 mcu为例子,说明下具体实现。
extern void vPortYield( void ) __attribute__ ( ( naked ) );
#define portYIELD() vPortYield()
* Manual context switch. The first thing we do is save the registers so we
* can use a naked attribute.
void vPortYield( void ) __attribute__ ( ( naked ) );
void vPortYield( void )
{
portSAVE_CONTEXT();