
任务的切换是在Pendsv中断服务中实现的,如何在这个中断服务程序中实现多优先级的任务切换
多优先级切换
实质:让全局指针pxCurrenTCB在任务切换(taskYIELD)的时候,指向了最高优先级的任务的TCB
实现方法:共有两种方法
通用方法:
本质上就是遍历数组,遍历就绪列表pxReadyTaskLists(它是一个数组),每一个数组下标就对应一个优先级,如果对应的优先级下的链表里没有任务存在,那么就将变量uxTopPriority减一,然后接着判断;如果存在任务,那么就将当前uxTopPriority的值赋值给uxTopReadyPriority,代表当前的最高优先级,然后将这个最高优先级的就绪任务对应的TCB更新到pxCurrenTCB。
针对特定处理器的方法:
这个就是要针对特定内核的处理器,就如STM32采用的Cortex-M内核
实现方法:通过Cortex-M内核的前导零指令 _CLZ()
前导零指令:这个指令的作用就是可以快速的算出一个32位(cortex—M内核单片机的变量为32位)变量uxTopReadyPriority,从高位开始到第一次出现1的位之间有多少个零,此时的uxTopReadyPriority和通用方法中的变量uxTopReadyPriority是不一样的,此时的这个变量是作为一个优先级位图表的角色,每一个位就代表一个优先级,32位对应32个优先级,如果对应优先级的任务就绪,那么就会将对应的位置1。
举个例子:例如优先级25、21、10都有任务就绪,那么uxTopReadyPriority变量对应的25位、21位、10位都将会被置1,然后通过(31-_CLZ(uxTopReadyPriority))=25,就得到了最高优先级是25,然后将这个最高优先级的就绪任务对应的TCB更新到pxCurrenTCB。这样就不要从最高级的优先级31开始向下遍历,到25才知道当前系统的最高优先级是25.