已经知道freeRTOS的任务切换函数发生在systick中断中,如下图
由上图可见,任务切换有个先决条件TaskIncrementTick()函数返回为1,这个函数如下图,
第564行是判断如果延时时间到的任务比当前任务优先级高,使能切换,这个自然是正常逻辑。
其中等于的情况也包含了,不然如果不切换的话会一直执行一个任务,配合任务切换函数用的是listGET_OWNER_OF_NEXT_ENTRY,总是指向下一个节点任务,既使不使能时间片抢占,同优先级任务到期也可以依次切换执行。
如果是大于的情况,那么使用listGET_OWNER_OF_NEXT_ENTRY也是指向当前到期的任务,因为taskSELECT_HIGHEST_PRIORITY_TASK()函数实现里关于listGET_OWNER_OF_NEXT_ENTRY()的函数实现里( pxConstList )->pxIndex总是指向end节点之前,而时间到期插入就绪任务时使用的是insertEnd();总是插入最后一个节点,即便前面还有一个节点也不会错过这个节点。
第576行至第582行就是判断是否执行实现时间片抢占的部分,第570行是个宏定义在配置文件中,
第579行是判断当前任务优先级链表里是否有其他任务,如果有使能切换
下图是任务切换taskYIELD();的最终实现,依次调用:
最后一个函数第120行就实现了将想要切换的任务的任务控制块指针赋值给pxCurrentTCB.
pendSV 最终根据pxCurrentTCB 第一项指示的栈顶地址,将任务栈的内容更改到msp的指针以及PC的指针以及其他寄存器实现任务切换。