现在的位置: 首页 > 综合 > 正文

根据ucos任务调度方法,自己设计的一个16个任务的调度器

2014年11月16日 ⁄ 综合 ⁄ 共 1352字 ⁄ 字号 评论关闭

根据自己的理解设计的也不道对不对,希望高人指点指点...

 

每个任务的就绪态标志放入在就绪表中,就绪表中有两个变量OSRdyGrpOSRdyTbl[]

 

OSRdyGrp中,任务按优先级分组,4个任务为一组。OSRdyGrp中的每一位表示4组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置位。

 

对于整数OSRdyTbl[i]0£i£3),若它的某一位
1,则OSRdyGrp的第i位为1

任务的优先级由XY确定

 

通过对组变量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]的值,可以最高优先级任务优先级号OSPrioHighRdyYY(上图)的值.

通过查找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();

}

 

 

抱歉!评论已关闭.