介绍下任务优先级小于64的情况。
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.总结
这种问题个人感觉可以现在网上浏览下别人的理解,但是我总是不能完全看懂别人的说法,可能理解方式不同,因此看到差不多的时候可以看着代码分析,这样可以更快理解。