最近在做ucosiii的移植工作,使用的板子是基于STM32F407的飞控板。目的是通过把以往的飞控程序上操作系统来体验一下。
ucos的任务调度机理其实还是比较简单的,大体是要先设置一个时钟节拍(以STM32为例是滴答定时器)作为内核的心脏,心脏每次泵血即一个时钟节拍到来就会进入中断OSTickISR()(STM32是Systick_Handler()),里面有三个函数
OSIntEnter()——中断嵌套层数+1
OSTimeTick()——维持内核时序,提供钩子函数允许用户加自己任务代码,不过不要太多毕竟在中断函数中
OSIntExit()——嵌套层数-1,查找任务就绪表,寻找最高优先级任务,做任务切换
OSIntExit()使用的任务切换函数是OSIntCtxSw()而非OSCtxSw(),二者区别在于前者无需再将被中断的任务进行现场保护(寄存器入栈操作)因为进入时钟节拍中断已经做了这部分操作。
所以内核就是通过时钟节拍一直选取任务就绪表中优先级最高的任务来执行,这里面也说明了问题,如果有的任务优先级不够高,而正在执行的程序不能被打断(比如在执行时序严格的驱动程序SPI、I2C等)最好要做保护,可以使用两种方法。一禁止中断,二禁止任务调度。第一种方式还是谨慎点用吧,毕竟会影响响应紧急任务的执行。第二种方式只可以防止被高优先级任务打断。