uCOs 查找最高优先级任务的方法和我个人的见解
2016-11-17 19:50
204 查看
之前自己在研究 ucos-II内核调度的时候,对于内核查找最高优先级的方法进行了一些总结,下面结合一些代码进行讲解!
uCos-II的优先级是值越小,优先级越高。在创建task的时候,传入一个prio的参数,就是优先级,比如prio == 12;
ptcb->OSTCBY = (INT8U)(prio >> 3u);//获取优先级的bit 3,4,5
ptcb->OSTCBX = (INT8U)(prio & 0x07u);//获取优先级的bit 0,1,2
ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY);
ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX);
OSRdyGrp |= ptcb->OSTCBBitY;//赋值到OS就绪组里面
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;//赋值到OS就绪组对于的Tbl里面
就想下图所示,OSRdyGrp放着高三位对应的bit位,自己想想3+3=6bit,6bit可以表示64个优先级,所以高3位对应OSRdyGrp,因为2的3次方 == 8,
比如prio == 12 == 0x0A= 0b 0000 1010,划分3位和3为的话,高3为为001 ,低3位为 010.
所以OSRdyGrp需要 | bit1位,如果高3位为 011,则OSRdyGrp需要 | bit3位,
低3位的原理也是一样的,OSRdyTbl[高3位的值] | == OSRdyTbl[1| |= 2 == 0b 010,就如下图优先级10所在的位置。
表 - 1
INT8U const OSUnMapTbl[256] = {
0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x00 to 0x0F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x10 to 0x1F */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x20 to 0x2F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x30 to 0x3F */
6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x40 to 0x4F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x50 to 0x5F */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x60 to 0x6F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x70 to 0x7F */
7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x80 to 0x8F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x90 to 0x9F */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xA0 to 0xAF */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xB0 to 0xBF */
6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xC0 to 0xCF */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xD0 to 0xDF */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xE0 to 0xEF */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u /* 0xF0 to 0xFF */
};
下面介绍一下 在调度的时候怎样获取最高优先级。
代码如下:
y = OSUnMapTbl[OSRdyGrp]; //查找高3位
x = OSUnMapTbl[OSRdyTbl[y]];//查找低3位
prio = (INT8U)((y << 3u) + x);
其实最高优先级是数值越小的,所以你看 表 - 1 的时候,想法是找OSRdyGrp里面bit0 到bit7 中,最先置为1的那位,然后根据找到了OSRdyGrp最低位,假设是Y,Y<=8,再从OSRdyTbl[Y]里面 bit0 到bit7 中,最先置为1的那位,假设为X,接下来就可以算出优先级最高的是那个了,根据这个想法,就容易明白OSUnMapTbl的表了,其实就是这个原理了,可以举例试一下,比如最高优先级为10时,高3位为001,即 OSRdyGrp
bit1位置1,所以OSRdyGrp 值等于 2,
即OSUnMapTbl[2] = 0x01,所以y == 1了,同理也可以得出 x == 2,所以就可以算出prio
== 10了,其实这些都可以自己举个例子,试一下就很容易明白里面的东西原理,当有多个任务时,他们的优先级分别为10,34,15,。根据这种方法,也可以得到最高优先级是10的结果的!
其实我个人也有一些想法,如果不想以牺牲空间换时间的话,也可以用2个for循环来找最高优先级。
for(i=0;i<8;i++)
{
if(OSRdyGrp>>i & 0x01)//找到最小bit位为1的时候
{
y = i;
break;
}
}
for(i=0;i<8;i++)
{
if(OSRdyGTbl[y]>>i & 0x01)//找到最小bit位为1的时候
{
x = i;
break;
}
}
prio = (INT8U)((y << 3u) + x);
这样时间复杂度最大的时候为O(16),也是一种查找优先级的方法,大家也可以讨论并测试一下!!
这次就先写到这了!下次再写!
uCos-II的优先级是值越小,优先级越高。在创建task的时候,传入一个prio的参数,就是优先级,比如prio == 12;
ptcb->OSTCBY = (INT8U)(prio >> 3u);//获取优先级的bit 3,4,5
ptcb->OSTCBX = (INT8U)(prio & 0x07u);//获取优先级的bit 0,1,2
ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY);
ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX);
OSRdyGrp |= ptcb->OSTCBBitY;//赋值到OS就绪组里面
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;//赋值到OS就绪组对于的Tbl里面
就想下图所示,OSRdyGrp放着高三位对应的bit位,自己想想3+3=6bit,6bit可以表示64个优先级,所以高3位对应OSRdyGrp,因为2的3次方 == 8,
比如prio == 12 == 0x0A= 0b 0000 1010,划分3位和3为的话,高3为为001 ,低3位为 010.
所以OSRdyGrp需要 | bit1位,如果高3位为 011,则OSRdyGrp需要 | bit3位,
低3位的原理也是一样的,OSRdyTbl[高3位的值] | == OSRdyTbl[1| |= 2 == 0b 010,就如下图优先级10所在的位置。
表 - 1
INT8U const OSUnMapTbl[256] = {
0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x00 to 0x0F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x10 to 0x1F */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x20 to 0x2F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x30 to 0x3F */
6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x40 to 0x4F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x50 to 0x5F */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x60 to 0x6F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x70 to 0x7F */
7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x80 to 0x8F */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x90 to 0x9F */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xA0 to 0xAF */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xB0 to 0xBF */
6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xC0 to 0xCF */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xD0 to 0xDF */
5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xE0 to 0xEF */
4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u /* 0xF0 to 0xFF */
};
下面介绍一下 在调度的时候怎样获取最高优先级。
代码如下:
y = OSUnMapTbl[OSRdyGrp]; //查找高3位
x = OSUnMapTbl[OSRdyTbl[y]];//查找低3位
prio = (INT8U)((y << 3u) + x);
其实最高优先级是数值越小的,所以你看 表 - 1 的时候,想法是找OSRdyGrp里面bit0 到bit7 中,最先置为1的那位,然后根据找到了OSRdyGrp最低位,假设是Y,Y<=8,再从OSRdyTbl[Y]里面 bit0 到bit7 中,最先置为1的那位,假设为X,接下来就可以算出优先级最高的是那个了,根据这个想法,就容易明白OSUnMapTbl的表了,其实就是这个原理了,可以举例试一下,比如最高优先级为10时,高3位为001,即 OSRdyGrp
bit1位置1,所以OSRdyGrp 值等于 2,
即OSUnMapTbl[2] = 0x01,所以y == 1了,同理也可以得出 x == 2,所以就可以算出prio
== 10了,其实这些都可以自己举个例子,试一下就很容易明白里面的东西原理,当有多个任务时,他们的优先级分别为10,34,15,。根据这种方法,也可以得到最高优先级是10的结果的!
其实我个人也有一些想法,如果不想以牺牲空间换时间的话,也可以用2个for循环来找最高优先级。
for(i=0;i<8;i++)
{
if(OSRdyGrp>>i & 0x01)//找到最小bit位为1的时候
{
y = i;
break;
}
}
for(i=0;i<8;i++)
{
if(OSRdyGTbl[y]>>i & 0x01)//找到最小bit位为1的时候
{
x = i;
break;
}
}
prio = (INT8U)((y << 3u) + x);
这样时间复杂度最大的时候为O(16),也是一种查找优先级的方法,大家也可以讨论并测试一下!!
这次就先写到这了!下次再写!
相关文章推荐
- ucos 获取查找最高优先级任务算法
- ucos 最高任务优先级 OS_SchedNew () 最高256个优先级 源码分析
- 对uC/OS-II查找最高优先级就绪任务算法的理解
- Ucos-ii中获取最高优先级的原理(任务和事件)
- ucos 就绪表(Ready List):任务设置,清除和查表最高优先级任务
- dodo:人脸识别方法个人见解 (zz)
- ucos-II之任务优先级
- google排序方法个人小见解
- 【转】dodo:人脸识别方法个人见解(一)
- 根据ucos任务调度方法,自己设计的一个16个任务的调度器
- ucos在s3c2410上运行过程整体剖析(9)---两种任务切换的实现方法
- .Net平台中虚方法的好处之个人见解
- 【djyos与uCOS】uCOS 不支持同优先级任务的调度,djyos可以
- 我的注入方法之个人见解!
- 关于repaint()和validate()方法区别的个人见解
- 人脸识别方法个人见解
- ucos在s3c2410上运行过程整体剖析---两种任务切换的实现方法 分类: μc /os ii 系统有关知识 2012-03-13 21:41 1102人阅读 评论(0) 收藏
- 人脸识别方法个人见解
- 软件架构的心得以及个人见解和方法
- ucos 任务优先级解析