ucos 任务优先级计算详解

介绍下任务优先级小于64的情况。


1.首先看下任务优先级介绍的图片,这个图比较直观,也是中文的,从网上拷贝的:

ucos 任务优先级计算详解_第1张图片



2.几个变量说明下:

OS_PRIO:可以理解为任务创建时分配的优先级,YYY表示任务优先级组,即OSRdyGrp,XXX表示组中的某一位。比如YYY为1,XXX为2,则可以对应到OSRdyTbl中的10。

OSRdyGrp:每一个bit代表一个组,一共8组,每组管理8个任务(具体哪一个记录在OSRdyTbl中),即为INT8U类型。

OSRdyTbl:每一个bit代表一个优先级,对应上图中的优先级准备表,即为INT8U  OSRdyTbl[8]类型。可以理解为8*8,0~63

INT8U const OSUnMapTbl[256] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             */
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             */
};  这个表对应了0~255中最低位1所在的位置,因为数值越小优先级越高,因此创建了这个表,其中第一行
0u==0x00 ==00000000b 最低位为1的位数为 bit0==0u (其实为空,空的情况默认为0,不影响计算)
1u==0x01 ==00000001b 最低位为1的位数为 bit0==0u
2u==0x02 ==00000010b 最低位为1的位数为 bit1==1u
3u==0x03 ==00000011b 最低位为1的位数为 bit0==0u (有两个为1的位,bit0,bit1,取最小的,因为OSRdyGrp或OSOSRdyTbl中最小的位数 对应的优先级越大)
4u==0x04 ==00000100b 最低位为1的位数为 bit2==2u
5u==0x05 ==00000101b 最低位为1的位数为 bit0==0u
6u==0x06 ==00000110b 最低位为1的位数为 bit1==1u
7u==0x07 ==00000111b 最低位为1的位数为 bit0==0u
8u==0x08 ==00001000b 最低位为1的位数为 bit3==3u
9u==0x09 ==00001001b 最低位为1的位数为 bit0==0u
Au==0x0A ==00001010b 最低位为1的位数为 bit1==1u
Bu==0x0B ==00001011b 最低位为1的位数为 bit0==0u
Cu==0x0C ==00001100b 最低位为1的位数为 bit2==2u
Du==0x0D ==00001101b 最低位为1的位数为 bit0==0u
Eu==0x0E ==00001110b 最低位为1的位数为 bit1==1u
Fu==0x0F ==00001111b 最低位为1的位数为 bit0==0u


3.计算公式

OSPrioHighRdy = 优先级组序号*8 + 该优先级组中序号,即上面说的YYY,XXX


4.跟着源代码走一遍

(1)OS_TCBInit()任务块初始化中,ptcb->OSTCBPrio   = prio;将创建任务时的优先级赋值给任务块。


(2)OSMutexPend()中 ptcb->OSTCBY    = (INT8U)( ptcb->OSTCBPrio >> 3); 优先级组序号
                                                 ptcb->OSTCBX    = (INT8U)( ptcb->OSTCBPrio & 0x07);  该组中优先级对应bit的位置
                                                 ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
                                                 ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);  优先级对应位置1


(3)OSRdyGrp  |=  ptcb->OSTCBBitY;  对应的组序号置1         
          OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; 对应该组中的相应优先级位置1


(4)y  = OSUnMapTbl[OSRdyGrp]; 取出优先级最高的组序号
          OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);  计算优先级,这里用到了OSUnMapTbl,当OSRdyGrp第1位为1时,不管其他为是多少,取到的值都是0,所以可以y  = OSUnMapTbl[OSRdyGrp];这样写。


5.总结

这种问题个人感觉可以现在网上浏览下别人的理解,但是我总是不能完全看懂别人的说法,可能理解方式不同,因此看到差不多的时候可以看着代码分析,这样可以更快理解。

你可能感兴趣的:(ucos 任务优先级计算详解)