您的位置:首页 > 其它

uC/OS II task find high ready task

2012-11-21 00:53 267 查看
uC/OS II在进行任务调度的时候会执行一个判断优先级的算法,通过Y和X来定位到具体的优先级。优先级各不相同,每个优先级即代表各自的task。

总共的task数量为:OS_LOWEST_PRIO+1,OS_LOWEST_PRIO需要>=1. OS_LOWEST_PRIO为idle task, 当OS_TASK_STAT_EN定义为1时,OS_LOWEST_PRIO-1为stat task(计算cpu使用率)。

Y:代表task所在的组;uCOS分了最多8个组。每个组有8个任务。最多支持64个任务。减去系统使用的一个idle(或者idle和stat),用户最多可以定义63 (62)个任务。

X: 代表该task在所属组中的位。

为什么要用这个方法来定义优先级呢?为了查找方便,管理方便?

优先级Prio =二进制 (b)00YYYXXX组成,YYY三位表示所在的组,XXX三位表示所属组中的位。比如优先级为20,则:

Y = 20>>3 = 2;

X = 20&0×7 = 4;

表示group为2,在group 2中的位为4.

以下例子以OS_LOWEST_PRIO为7做演示,即有7个任务,OS_TASK_STAT_EN=0,则有6个用户task:

OS_LOWEST_PRIO = 7

OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */

= OSRdyTbl[((OS_LOWEST_PRIO) / 8 + 1) ] = OSRdyTbl[1]

设:OSRdyTbl [OS_LOWEST_PRIO/8 + 1] = 0010 1100 = 0x2C //所有为ready状态的task。有5,3,2位。

则:OSRdyGrp = 0000 0001

OSUnMapTbl[OSRdyGrp] = OSUnMapTbl[0x01] = 0

y = OSUnMapTbl[OSRdyGrp] = 0

x = OSUnMapTbl[OSRdyTbl[y]] = OSUnMapTbl[OSRdyTbl[0]] = OSUnMapTbl[0x2C] = 2

所以:

OSPrioHighRdy = y<<3 + x = 0<<3 + 2 = 2

OSPrioHighRdy = (INT8U)((y << 3) + 1) = 2;

OSPrioCur = OSPrioHighRdy;

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

OSTCBCur = OSTCBHighRdy;

OSPrioCur = 2;

OSTCBHighRdy = OSTCBPrioTbl[2]; // *OSTCBPrioTbl[OS_LOWEST_PRIO + 1];/* Table of pointers to created TCBs */

即:处于ready状态,优先级最高的为2.

附:

INT8U const OSUnMapTbl[] = {

0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×00 to 0x0F */

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×10 to 0x1F */

5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×20 to 0x2F */

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×30 to 0x3F */

6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×40 to 0x4F */

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×50 to 0x5F */

5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×60 to 0x6F */

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×70 to 0x7F */

7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×80 to 0x8F */

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0×90 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 */

};

//调度算法

void OS_Sched (void)

{

……

y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */

OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);

if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

OSCtxSwCtr++; /* Increment context switch counter */

OS_TASK_SW(); /* Perform a context switch */

}

……

}

Posted by Ian at 02:23 Tagged with: 调度算法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: