当前位置:首页 > 嵌入式 > 嵌入式软件
[导读]μC/OS是Jean J.Labrosse开发的实时多任务内核,最初是为Motorola 8位处理器68HC11写的。在后来的相关著作中,作者将代码移植到了PC上,以便于更多的读者学习。μC/OSII继承了μC/OS的算法,有执行效率高、占用空间小、实时性强和可扩展性好等特点,被移植到几乎所有类型的CPU上,成为在嵌入式领域非常有影响力的RTOS。然而,由于该实时内核是为8位CPU设计的,对于那些具有优先级算法硬件指令的CPU,仅做移植是很不够的。

μ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的占用。

4 改进扩展任务数的优先级调度性能

当对μC/OSII支持的任务数进行扩展时,按照μC/OSII原有的做法,需要按照高低字节分别查找OSUnMapTbl对照表。任务数为256时,寻找最高优先级就绪任务的函数将需要运行约35条指令。数出前导零数目的指令在这种情况下的作用将更加显著,对于32位PowerPC处理器,精心设计的代码可以做到仅需10条指令就将任务数扩展到1024个。

此时OSRdyGrp扩展为32位,OSrdyTbl扩展成32个32位的数组。从OSRdyGrp得到的前导零数目,就是任务优先级高5位的值,乘以4可以得到该字的相对偏移地址;在OSRdyTbl中,定义高位对应高优先级任务,低位对应低优先级任务,则其前导零数目就是任务优先级低5位的值,和高5位的值移位相加就得到完整的任务优先级。通过将OSRdyGrp和OSRdyTbl定义成结构体,利用结构体首地址的相对寻址来分别读取其数值,可以减少一次取地址的操作。

寻找最高优先级就绪态的最终代码如下:

在64位的PowerPC 更有cntlzd(Count Leading Zero Double word)指令,一次就可以找出64个任务中优先级最高的那个,就更没有必要使用μC/OS?II中的算法了。

5 总结

RTOS实时内核μC/OS和μC/OS?II中,任务调度算法巧妙,性能优异,在嵌入式应用领域很有影响力,被移植到各种CPU上。然而由于是为8位CPU设计的,对于那些具有优先级硬件算法指令的16/32/64位CPU,μC/OS?II的软件算法就完全失去了优势。应该利用这类CPU的特有指令,优化任务调度算法,使RTOS的实时性达到最佳。对于这类处理器,仅移植μC/OS?II软件算法是很不够的,应该利用相关硬件算法指令。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭