在内核中有两张核心常量表: 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] |
|