1、ucos2采用抢占式的实时调度算法,调度原则:在每一个systic中断中,系统都要判断当前系统64个任务中,所有处于就绪态的任务里,谁的优先级最高就去执行谁。
2、就绪表设计。
自己想象设计就绪表:
u8 rdyTbl[8] // 数组总共是64个位,分成8个字节。每一个位表示一个任务的状态。0表示非就绪。1表示就绪。这样是可以省内存,但是优先级不能直接作为数组下标使用了。
if((rdyTbl[1] & 0x80) == 0x80) // 判断优先级为15的任务是否是就绪态。
rdyTbl[0] |= (1<<3);// 将优先级为3的任务设为就绪态。
rdyTbl[1] &= ~(1<<5) // 将优先级为13的任务设置为非就绪态。
总结:
rdyTbl[n/8] |= (1 << (n%8)) // 将任务优先级为n的任务设为就绪态
rdyTbl[n] &= ~(1<<(n%8)) // 将任务优先级为n的任务设为非就绪态
ucos系统源代码就绪表设计:
(1)一个bit表示一个任务状态,组成8*8的矩阵
(2)纵向OSRdyGrp一个bit囊括一个组中8个任务。
(3)横向OSRdyTbl[8]中每一个元素的8个bit分别对应组中的8个任务。
(4)0表示非就绪态,1表示就绪态。
(5)查表时先查OSRdyGrp,再根据结果查有就绪任务的组。实际上性能提升点在于省区了对没有就绪态的组中8个任务的遍历过程。
OSRdyTbl中一个组中8个任务的就绪态全部是0时,这个组的OSRdyGrp对应的位才是0.只要有1个1,对应的OSRdyGrp的位就是1.
OSRdyGrp这个变量也是拆成8个位来使用的,这个变量的值反映了哪个组中是有就绪任务的。假设OSRdyGrp的值为0x00,说明64个任务全部处于非就绪态。(此时就不需要去查OSRdyTbl就知道了)。假设OSRdyGrp的值为0x04,说明第2组(0x04是0b00000100,bit2为1,对应第2组),有任务处于就绪态。
如果OSRdyGrp为0xff代表8个组中都有就绪态的任务,这时候就需要全部去遍历。现实中,这种情况时不存在的。基于两点原因:1、现实中基本不可能存在64个任务之类的如此多的任务项目。2、设计任务时,各个任务优先级基本上是相邻有序排列的,很少有较为分散的分布到8个组中的。因此OSRdyGrp的引入大大提升了程序的性能。