uc/os-ii中最高优先级计算(如何查表)

86 阅读4分钟
  • 为什么要引入优先级表?

    Answer:uc/os-ii是个讲究实时性的操作系统,在有多个任务时,系统需要选择这些任务中优先级最高的任务进行调度。如果单靠计算,有的优先级计算费时少,有的很多,实时性得不到保证。如果引入表,我们只要知道表的横纵坐标就可以直接找到需要的任务,实时性可以得到保证。因此,引入优先级表。

  • 优先级表(OSUnMapTbl)和就绪表(OSRdyTbl)、就绪组(OSRdyGrp)的关系?如何计算优先级?

    Answer:实际上是位图和表格的结合。

    从代码上看,如下所示:

i = OSUnMapTbl[OSRdyGrp] ;// 找到行号
j = OSUnMapTbl[OSRdyTbl[i]];//找到列号
TaskPrior = 8*i+j=(i<<3)+ j;//找到最高优先级号。

    具体解释为:

1.在OSUnMapTbl表中找到第OSRdyGrp位对应的数字,该数字赋值给i,代表优先级所在的行号;

2.在OSUnMapTbl表中找到第OSRdyTbl[i] 位对应的数字,该数字赋值给j,代表优先级所在的列号;

3.看就绪表中i行j列对应的数值。该数值为当前任务中最高的优先级。

    就绪表如下所示:

\

这个表是我们将OSRdyGrp和OSRdyTbl二者结合构成的。如下图:

\

合成之后就是我们看到的二维的一个表。但是该表实际上并不是以二维形式存在的。

因此,我们在知道横纵坐标之后,不能直接查表,而是进行一个简单的计算,即上述代码语句第三句。将i左移三位,实际上就是i*8(OSRdyTbl是8位,即一行有8位),然后加上在该行的偏移量,也就是j。这样就可以算出来优先级是多少了。这里需要提醒一下:OSRdyTbl坐标是从右往左递增的顺序,不要搞错了。

具体的操作我们举个例子来说明一下:

先把相关的图展示出来:

\

\

假设OSRdyGrp=98(d)=01100010(b);  

    第一步就是在第二个图所示的表(OSUnMapTbl)中查找第98位的数字,作为横坐标。注意一下:98是十进制的,十六进制为0x62。我们锁定注释为:/*0x60 to 0x6F*/这一行,从左边开始数(第一个数字数作0),2对应的表中的数字就是1u。所以i=1,即横坐标是1。

    第二步:得到OSRdyTbl[i]对应的值并计算纵坐标。i值第一步计算出来了,所以OSRdyTbl[i]=OSRdyTbl[1]。假设此时OSRdyTbl[1]=01100000(b)=96(d)。我们需要做的就是在OSUnMapTbl表中查找第96位的数字,查找方式和第一步一样。可以看到数值为5u。所以j=5,即纵坐标是5。

    第三步:计算最高优先级任务对应的优先级。i*8+j=13。所以最高优先级任务对应的优先级为13。\

我们检验一下,在第一个图中拼凑的的二维表中,1行5列的数值就是13。说明我们计算正确。

可能有人还有疑问:在计算机内我们给的值是什么?难道不直接是优先级?

Answer:我们给定的是两个值:OSRdyGrp和OSRdyTbl值,根据这两个值找对应的优先级。

又问:为什么不直接给优先级然后进行比较找到最高优先级任务?

Answer:我们前面提到过,uc/os-ii要保证实时性才引入了表格。在一堆任务中找最高优先级任务,如果直接给每个任务的优先级,我们就需要两两比较,或者将其排序,时间得不到保证。试想一下,如果只有三个任务,找最高优先级任务很容易。但如果是30个,300个呢?显然,用表格查找更符合我们的要求。

还问:那我们怎么从给的两个值知道所有任务的优先级或者说怎样从这两个值看出来有几个任务,各自优先级又是多少?

Answer:回到上面的例子:OSRdyGrp=0110 0010,OSRdyTbl=0110 0000。OSRdyGrp的第1,5,6位为1,那么就绪组就有3个。OSRdyTbl的第5,6位为1,那么就绪表有2个任务。总共是3*2=6个任务。优先级分别是(数值从低到高):13,14,45,46,53,54。\

\

这里附加介绍一下简单的找优先级的方法:

我们知道优先级越高,数值越低。所以我们只需要保证取到 OSRdyGrp和OSRdyTbl 的最低置1位就可以。还是上面的例子。98=0110 0010,最低置1位是第一位,所以横坐标就是1。96=0110 0000,最低置1位是第5位,所以纵坐标是5。这样就可以计算得到最高优先级任务对应的优先级是多少了。

以上解释均为个人想法,不当之处还望指出。