μC/OS是Jean J.Labrosse开发的实时多使命内核,开始是为Motorola 8位处理器68HC11写的。在后来的相关作品中,作者将代码移植到了PC上,以便于更多的读者学习。μC/OSII承继了μC/OS的算法,有履行效率高、占用空间小、实时性强和可扩展性好等特色,被移植到简直一切类型的CPU上,成为在嵌入式范畴十分有影响力的RTOS。但是,因为该实时内核是为8位CPU规划的,关于那些具有优先级算法硬件指令的CPU,仅做移植是很不行的。
1 依据优先级的使命调度
一个依据优先级的实时多使命内核的使命调度机制需求完结下面三个中心的处理功用:
◆ 将使命置于安排妥当态;
◆ 将使命撤销安排妥当态;
◆ 找出最高优先级的安排妥当态使命。
在32位机上运转64个使命,可运用两个32位的整型变量数组OSRdyTbl [2],树立一个64位的使命安排妥当态向量;每一位表明对应优先级的使命是否处于安排妥当态,例如OSRdyTbl [0]的第4位为1表明优先级为4的使命处于安排妥当态。结构如下的三个函数,用来完结设置使命安排妥当、撤销使命安排妥当和寻觅当时最高优先级的安排妥当使命。
上述代码可在任何处理器上完结所需的功用,没有考虑任何的优化和改善。经过这样的原理性函数,能够更好地了解多使命内核的使命调度。
寻觅最高优先级安排妥当态使命的函数调用频率高,其履行时刻直接影响内核的使命切换推迟时刻,影响体系实时性。上述寻觅最高优先级的安排妥当态使命的代码,随当时安排妥当使命的优先级不同,其循环次数也不同,导致其运转时刻不确定。
2 μC/OS的使命调度完结办法
μC/OS和μC/OSII是为8位CPU写的,选用8位机算法,支撑64个使命。运用8个字节的OSRdyTbl大局数组,表明一切使命的安排妥当态信息:1为使命安排妥当,0为非安排妥当。数组第一个字节的b0位代表64个使命中优先级最高的使命,最终一个字节的b7位代表优先级最低的闲暇使命,永远为1。当OSRdyTbl 数组的数据不为0时(表明对应的8个使命中至少有1个进入安排妥当态),另一个单字节大局变量OSRdyGrp 中的相应位要置1。当使命状况发生变化时,需更新OSRdyGrp和OSRdyTbl中对应的位。
寻觅最高优先级的安排妥当使命时,μC/OS运用了预先固化的256字节的对照表OSUnMapTbl,给出特定字节值的最低位1所在位的信息。查表算法防止了逐位检测各优先级位引起的履行时刻的不确定性,程序简略,履行速度快,与安排妥当使命多少和优先级无关。
关于取值0~63的使命优先级,μC/OS将其划分红高3位的Y和低3位的X,并保存在其使命操控块TCB的OSTCBX和OSTCBY中,其对应的OSUnMapTbl的值保存在OSTCBBitY和OSTCBBitX变量中,以进步运算速度。为了防止函数调用所带来的额定开支,μC/OS直接用句子完结如下的三部分功用。
① 设置使命进入安排妥当态
OSRdyGrp |= ptcb>OSTCBBitY;
OSRdyTbl[ptcb博OSTCBY] |= ptcb>OSTCBBitX;
② 设置使命退出安排妥当态。
y = OSTCBCur>OSTCBY;
OSRdyTbl[y] = ~OSTCBCur>OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp = ~OSTCBCur>OSTCBBitY;
}
③ 寻觅最高优先级的安排妥当态使命。以OSRdyGrp的值做偏移量,查OSUnMapTbl表,得到1个0到7的数Y,作为优先级高3位,再依据Y的值,找出OSRdyTbl中对应的字节,而且再次查OSUnMapTbl表,得到1个0到7的数X,作为优先级低3位的值,经过将Y左移3位再加上X的值,得到安排妥当使命中优先级最高的那个。
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y 3) + OSUnMapTbl[OSRdyTbl[y]]);
μC/OS的使命调度算法选用了以空间换时刻的战略,将特定字节值的最低位1所在位的信息预先核算并保存到表中,运转时经过查表快速得到;每个使命的TCB中除了保存优先级信息本身外,还运用额定的4个字节保存优先级的凹凸3位和对应的OSUnMapTbl值,以防止运转时实时核算这几个值所带来的推迟。这些办法增加了体系ROM和RAM的开支。
3 运用PowerPC“数出前导零数目”指令完结使命调度
PowerPC是Motorola 、IBM和Apple三家公司于20世纪90年代初期联合规划的32位CPU。Freescale(其前身是Motorola半导体部)开展了针对轿车电子的MPC5xx系列单片机及后续依据e200内核的MPC5xxx系列单片机;更高端的e500、e600内核是用于通讯范畴的MPC6xxx、7xxx和8xxx系列。
下面临μC/OS使命优先级调度算法的改善和优化是在MPC5554单片机上完结的。
PowerPC处理器具有一条“数出前导零数目” 的指令cntlzw(count leADIng zero word),能够以硬件指令办法完结优先级的多使命调度算法。这条指令也可用于图画处理和算法加密的场合。该指令数出一个32位寄存器中前置零的数目,例如,回来0表明b0不为零,即没有前导零;回来3表明b3不为零,b3位的前面从b0到b2共有3个零;回来32表明RS寄存器中一切的位都为零。(在PowerPC架构中,最高位MSB表明为b0,低位MSB依据位宽表明为b7、b15或b31。)
运用这条指令,用汇编语言改写寻觅最高优先级的安排妥当使命的函数,则不需求进行循环移位判别,能够直接从64个使命中找出优先级最高的那个使命。代码如下:
在这段代码中,首要判别前32个使命是否有处于安排妥当态的,假如没有的话,再对后32个使命进行判别。因为优先级最低的闲暇使命总是处于安排妥当态,所今后32个使命总能回来一个有效值。该代码在前32个使命有安排妥当态时运转7条指令,在前32个使命均没有安排妥当时需求履行10条指令;而μC/OS原有的代码编译出来的汇编程序,则需求运转15条指令。
运用这个办法的另一个优点是不再需求运用256字节的OSUnMapTbl表,使命操控块TCB也不需求运用OSTCBX、OSTCBY和OSTCBBitY、OSTCBBitX变量,每个ECB中也不再需求OSRdyGrp,这也减少了对ROM和RAM的占用。