前言
- uCOS-II 中,为了更快的获取最高的优先级,使用了空间换取时间的方法,通过查找【优先级判定表】
PRIORITY RESOLUTION TABLE ,很快的获取最高优先级 - uCOS-II 对优先级用 【位】来表示,并分组,每组 8个优先级,最大优先级为 64,优先级 组 有一个8位字节表示,如 64 个优先级, 8个字节表示优先级的每个位,一个优先级组字节,表示分组
- 优先级0 为最高优先级,0 位于 0 组, OSRdyGrp[0]中的 BIT0
- 因为【低位】的优先级高于【高位】的优先级,每个字节的8位中,获取首个1出现的位置即可。
查找算法
- 从优先级分组中,从【低位】开始,找到第一个【分组】,如0x03,第一个分组为:BIT0,0组,可以用 Y (纵坐标)表示
- 通过上面的分组,从【低位】开始,找到第一个【1】,这就是最小的也是最高的优先级,可以用 X 表示
- 通过公式:
最高优先级 = 分组 Y * 8 + X(组员)
计算方法
- 对于一个数,8位或32位,二进制查看,从【低位】 到 【高位】,查找第一个 1 出现的位置
- 如 数字 8, 二进制:00001000 ,返回:3 ,也就是 1<<3,低位开始,第一个1出现在位置3,或者BIT3
- 如数字 0x33,二进制: 00110011,返回 : 0, 也就是 1 << 0,地位开始,第一个1出现在位置0,或者BIT0
计算代码
- 这里使用RT-Thread 模拟器,visual studio 2022编译,shell命令的方式计算并打印
- get_ffs_value 模拟 : __builtin_ffs,获取从低位开始,第一个1 出现的位置,
rt_uint32_t get_ffs_value(rt_uint32_t value)
{
int num = 0;
if (value == 0x00)
{
return 0;
}
if ((value & 0xffff) == 0)
{
num += 16;
value >>= 16;
}
if ((value & 0xff) == 0)
{
num += 8;
value >>= 8;
}
if ((value & 0xf) == 0)
{
num += 4;
value >>= 4;
}
if ((value & 0x3) == 0)
{
num += 2;
value >>= 2;
}
if ((value & 0x1) == 0)
{
num += 1;
}
return num;
}
void ffs_test(void)
{
rt_kprintf("const rt_uint8_t __lowest_bit_bitmap[] =\r\n");
rt_kprintf("{\r\n");
for (int i = 0; i < 256; i++)
{
if (i % 16 == 0)
rt_kprintf(" ");
rt_kprintf("%d, ", get_ffs_value(i));
if ((i + 1) % 16 == 0)
rt_kprintf("\r\n");
}
rt_kprintf("};\r\n");
}
MSH_CMD_EXPORT(ffs_test, ffs test);
运行结果
const rt_uint8_t __lowest_bit_bitmap[] =
{
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,
};
INT8U const OSUnMapTbl[] = {
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
};
备注
- gcc 下的
__builtin_ffs ,可以获取 低位开始,第一个 1 出现的位置
小结
- 了解uCOS-II 优先级判定表的计算方法,查表方法比计算要快一些
|