μc/os-ii 是一种基于优先级的抢占式多任务实时操作系统,包含了实时内核、任务管理、时间管理、任务间通信同步(信号量,邮箱,消息 队列)和内存管理等功能。它可以使各个任务独立工作,互不干涉,很容易实现准时而且无误执行,使实时应用程序的设计和扩展变得容易,使应用程序的设计过程大为减化。
1 μc/os-ii的任务调度算法分析
1.1 μc/os-ii任务就绪表的解读
μc/os操作系统采用优先级至上的任务调度原则,让进入就绪态任务中优先级最高的那个任务,一进入就绪态就能立即运行。μc/os操作系统实现了一种巧妙的查表算法,利用这种算法能快速实现任务调度原则。如何从任务就绪表中,查找优先级最高的那个任务?归结起来:
两个变量(osrdygrp、osrdytb1[])和两张表(osmaptb1[]、osunmatb1[])。
μc/os操作系统可支持64个任务,每个任务被赋予不同的优先级——从0级到最低优先级os_lowest_prio,最末两个为操作系统所用,分别为统计任务和空闲任务的优先级。μc/os-ii任务就绪表如图1所示。判断任务就绪同样根据osrdytb1[]和osrdygrp两个变量来完成:osr-dytb1[]按任务优先级分成8组(即每一组8个任务优先级),当任务处于就绪状态时,对应的位为1,反之则为0;osrdytb1口组中任何一位为1时,对应的osrdygrp位置1。
图1 μc/os-ii任务就绪表
使任务进入就绪状态和脱离就绪状态,都是通过osrdytb1[]和osrdygrp这两个变量来查找osmaptb1[]表完成的:
①进入就绪状态。
任务优先级的低3位用于确定任务在总就绪表osrdytb1[]中的位置。紧接着前面的3位用于确定是osrclytb1[]数组的第几个元素,两个变量都置1。
②脱离就绪状态。
代码将就绪任务表数组osrdytb1[]中相应元素的相应位清0,而只有当这一组中的所有任务都为脱离就绪态时,osrdygrp变量才会为0。
1.2 高优先级任务的查找
从任务就绪表中查找最高优先级任务,即从osrdytb1[]变量中找到最低为1的位是第几位(对应的就是最高优先级任务)。μc/os-ii采用查表的方式来找出处于就绪态的最高优先级任务,μc/os-ii中有一张256个单元的数据表osunmaptb1[],表中按一定规律有128个o,64个1,32个2,16个3,8个4,4个5,2个6,1个7,还有1个0,共256字节。osunmaptb1[]的定义如下所示:
找出进入就绪态的最高优先级任务的代码如下:
初看这张表感觉杂乱无章,实际是很有规律的。以“osunmaptb1[0]~osunmaptb1[15]:0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x00~0x0f*/”为例说明:
其他依次类推。
下面再以一个实例进行说明:假设变量osrdygrp=01011000b,表示变量osrdytb1[3]、osrdytb1[4]、osrdytb1[6]有任务处于就绪状态,任务调度是去查找最高优先级任务(y=osunmaptb1[0x58])。由于srdytb1[3]>osrdytb1[4]>osrdytb1[6],结果y=3。如果osrdytb1[3]=1000 0001b,则通过查表x=os-unmaptb1[osrdytb1[3]],即可得到x=o,表明这组数中第0位为1处于最优状态。这样,prio=(y《3)+x=(3《3)+0=24。再利用这个优先级的值,查找任务控制块优先级表ostcbpriotb1[],得到指向任务的任务控制块os_tcb。
2 cortex-m3中μc/os-ii任务调度的硬件实现
cortex-m3采用精简指令集,采用thumb-2指令,其中包括基于rtos的硬件算法指令(clz),可以通过这种指令查找处于就绪态的最高优先级任务。μc/os-ii中任务的就绪态是反映在osrdytb1[]变量中,共计8字节(64位),对应64个任务。可以将其折分成两个32位的数据,然后分别查找这两个32位的数据中优先级最高的任务。先查找低32位,如果低32位中不为零,则找出其中最高优先级任务;否则查找高32位,找出其中最高优先级任务,高32位的的查找结果应加上数值32。
cotrex-m3中通过以下两条指令就可完成最高优先级任务的定位:rbit和clz。rbit的含义是把一个32位数据水平旋转180°;clz的含义是计算前导零的个数。
假设在osrdytb1[]的低32位数据中,00000000000000000000000000001100b表示优先级为2的任务和优先级为3的任务处于就绪态,现在要通过指令rbit和clz找出优先级为2的任务并调度运行。运行rbit后数据变为:
00110000000000000000000000000000000000。运行clz后计算出前导零的个数为2,表明优先级为2的任务处于最高就绪态。
μc/os-ii中的任务调度是通过查两次表完成最高优先级任务的查找,方法如下:
上述代码在mdk4.12软件中测试,系统时钟采用8 mhz,按照此方法进行任务调度可节省0.5μs,同时还减少了用来存放osunmaptb1[]的256字节的空间,缩短了代码运行时间,提高了cpu的利用率。此方法在μc/os-ii的任务通信中也同样适用。在此不再赘述。
结语
本文主要对μc/os-ii中的任务调度算法作了分析,特别阐述了osunmaptb1[]表是如何构成的,同时介绍了基于arm cortex-m3处理器平台的μc/os-ii的任务调度硬件实现方法,简化了μc/os-ii的代码,提高了处理器的性能。
英伟达收购Mellanox交易获得中国批准
艾德克斯IT8800系列直流电子负载发电机的测试方案
工信部发布了2018年7月份通信业经济运行情况
能识别身份的不止你的手,还有你的脚
三星希望通过下一代旗舰产品Galaxy 10和可折叠屏幕手机来渡过难关
基于ARM Cortex-M3处理器平台的μC/OS-II任务调度硬件实现
NVIDIA360度全方位立体视听系统:让你身临其境
STM32 ILI9341驱动TFTLCD(十)LCD显示汉字(补充)
使用LED矩阵的Arduino二进制时钟的制作教程
玻璃反光也能误识别?当自动驾驶遇到千奇百怪的corner case
无人送货时代什么时候可以到来
rom…import导入代码介绍
一加5拆解 内部做工究竟如何
科技如何塑造明日的健康之路?
LOTO虚拟示波器软件功能演示之——FIR数字滤波
小米9和荣耀V20哪个最值得买
发改委:以全面开放推动船舶工业高质量发展
烽火OPGW光缆提速铁路新基建
FPGA之主时钟约束解析
请教比较器和运放可以不经三极管而直接驱动光耦吗?