在内核中有两张核心常量表:
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 */
}; //
该表为:将0x00-0xff每个数据中最低位为1的位数一一列举出来。已就绪任务为例:给定一个OSRdyGrp变量值,就能够找到它非零的最低位的位置,比如 0x68 = (01101000)b,那么它的的最低位位置为3。从表中查找验证得为3。由于OSRdyGrp和OSRdTbl[]共同管理64个任务,OSRdyGrp的每一位管理一组,OSRdTbl[]中的每一个元素为一组,每组能够管理8个任务。
INT8U const OSMapTbl[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};//转化为二进制就很容易理解了。
该表是位掩码表,根据pro(优先级)关联,prio >> 3 得到的值就是y,也就是OSRdyGrp对应的位索引值,从而OSMap[prio >>3]的到一个对应位为1的数值,然后与OSRdyGrp“或”运算,置其对应位为1,同理OSMapTbl[prio &0x07] , pro& 0x07取得最低3位值x,该x对应OSRdyTbl[ y]的对应位掩码,然后同OSRdyTbl[ y]进行“或”运算,可使OSRdyTbl[y]对应位置1。
一、获取当前就绪队列中优先级最高的任务的优先级
1、 其实就是找到OSRdyGrp中为1的最低位y以及OSRdyTbl[y]中为1的最低位x,那么当前就绪队列中优先级最高任务的优先级为pro = y*8 +x 。(即 pro = (y << 3) + x)
2、那么OSUnMapTbl[],该表就是用空间换时间,直接把OSRdyGrp每一个取值对应的y直接索引出来(可以看出所有的奇数OSRdyGrp对应的元素都为0,这是因为奇数最低位为1, 那么 y = 0),其他的OSxxGrp变量求y值都是一样的。
二、创建优先级为prio的任务,使其进入就绪队列(让OSUnMapTbl[]的prio位置1)。
OSRdyGrp |= OSMapTbl [ prio >>3]
OSRdyTbl[pro >>3] |= OSMapTbl[prio &0x07]