对uC/OS-II查找最高优先级就绪任务算法的理解

因为最近想在 stm32 上跑操作系统,所以开始学习 uC/OS-II。正好这学期有嵌入式实时操作系统这门课,但上课的教材内容是广义上的嵌入式实时操作系统,所以我在图书馆借了任哲老师的这本“嵌入式实时操作系统 uC/OS-II 原理及应用”这本书。

最近看到任务就绪表及任务调度这部分,关于对任务就绪表的操作主要包括登记、注销和从就绪表的就绪任务中找到优先级最高的任务。

根据书本上的内容对任务的登记和注销的代码是比较好理解的,比较难理解的是查找优先级最高任务的算法。

再查找优先级最高的任务时,用到了 OSRdyGrp 这个变量,OSRdyTbl 这个数组以及 OSUnMapTbl 这个用于查找的数组,前面两个的含义书上都有讲,主要是对于那个用于查找的数组的用法不太清楚。

用于查找优先级最高就绪任务的代码很简单,如下:

y = OSUnMapTbl[OSRdyGrp]
x = OSUnMapTbl[OSRdyTbl[y]]
prio = (y << 3) + x

y 是优先级的高三位,x 是优先级的第三位。

OSUnMapTbl 数组如下:

INT8U const OSUnMapTbl[256] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };

要理解上面三句话我觉得主要是理解这个数组,确实通过举例子可以验证算法的正确性,但是我还是想知道这个数组是怎么生成的,所以稍微研究了一下。

下面就说一下我的理解:
因为要找优先级最高的任务,在 OSRdyGrp 里为 1 的最低位就是优先级最高任务所在的任务组,在 OSRdyTbl 的 8 个任务组里,为 1 的最低位就是优先级最高任务在这个任务组里的位置。所以找优先级最高的任务就是找他的高三位和第三位,就是找一个 0~7 之间的数值,就是找下标。

因为这只是记录一下自己的想法,所以说的不是那么清楚,顺便贴上自己写的生成那个用于查找数组的代码

#include <stdio.h>
#include <stdlib.h>

#define uint8 unsigned char

int main()
{
    uint8 redgrp;
    uint8 map[256] = { 0 };
    map[255] = 0;
    int i;

    for(redgrp=1;redgrp<255;redgrp++)
    {
        uint8 temp = redgrp;
        for(i=0;i<8;i++)
        {
            if((temp&0x01)!=0)
            {
                map[redgrp] = i;
                break;
            }
            else
            {
                temp>>=1;
            }
        }
    }

    for (i = 0; i<256; i++)
    {
        printf("%d ", map[i]);
        if ((i + 1) % 16 == 0)
            printf("\n");
    }

    return 0;
}

运行结果如下:
《对uC/OS-II查找最高优先级就绪任务算法的理解》
可以看到的确生成了那个数组,理解这个代码应该就理解 uC/0S-II 是怎么查找优先级最高的任务了。

    原文作者:查找算法
    原文地址: https://blog.csdn.net/qq_27833589/article/details/78374905
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞