分类: LINUX
2011-12-10 08:14:40
根据自己的理解设计的也不道对不对,希望高人指点指点...
每个任务的就绪态标志放入在就绪表中,就绪表中有两个变量OSRdyGrp和OSRdyTbl[]
在OSRdyGrp中,任务按优先级分组,4个任务为一组。OSRdyGrp中的每一位表示4组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置位。
对于整数OSRdyTbl[i](0£i£3),若它的某一位
为1,则OSRdyGrp的第i位为1。
任务的优先级由X和Y确定
通过对组变量OSRdyGrp和表变量OSRdyTbl进行如下操作,将任务就绪表中相应Bit位置1,就可以使Prior的任务进入就绪态.
OSRdyGrp |=OSMapTbl[prio>>2];
OSRdyTbl[prio>>2] |= OSMapTbl[prio&0x03];
其中OSMapTbl[]用于将组变量OSRdyGrp和表变量OSRdyTbl[]的相应位置1.
OSMapTbl[0] = 0000 0001
OSMapTbl[1] = 0000 0010
OSMapTbl[2] = 0000 0100
OSMapTbl[3] =0000 1000
有了任务就绪表,任务调度就变得简单了,只需要在任务就绪表中找到处于就绪态的优先级号最小的任务.
这里设计了一个数组OSUnMapTbl[16],通过查找OSUnMapTbl[OSRdyGrp]的值,可以最高优先级任务优先级号OSPrioHighRdy的YY(上图)的值.
通过查找OSUnMapTbl[OSRdyTbl[OSRdyGrp]]的值,得到XX的值.最后计算OSPrioHighRdy通过OSUnMapTbl[OSRdyGrp]<<2+ OSUnMapTbl[OSRdyTbl[OSUnMapTbl[OSRdyGrp]]]得到.
OSUnMapTbl[]={
0,0,1,0,
2,0,1,0,
3,0,1,0,
2,0,1,0,
}
例如,假如OSRdyGrp的二进制为1000,即0x8,查OSUnMapTbl[0x8]=3; 假如OSRdyTbl[3]的二进制为0001,即0x01,则查OSUnMapTbl[0x01]有值为0;最后得到就绪优先级的最高任务级号OSPrioHighRdy=3x4+0=12.
任务调度器算法为:
void OSSched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
if ((OSLockNesting | OSIntNesting) == 0) {
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y << 2) + OSUnMapTbl[OSRdyTbl[y]]);
if (OSPrioHighRdy != OSPrioCur) {
OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++;
OS_TASK_SW();
}
}
OS_EXIT_CRITICAL();
}
http://blog.csdn.net/xilibi2003/article/details/3601790