说明:这个函数由ucos的其他服务调用,用来决定即将运行的优先级最高的任务。它改变全局变量OSPrioHighRdy。
参数:无
返回值:无
注意:
这个函数是内部函数,外部应用无法调用。
这个函数被调用时,中断被假定为关闭。 //新版本提供了对256个任务的支持,由 OS_SchedNew函数计算出优先级再交给OS_Sched使用。 //书上的版本是没有这个函数的。 static
void
OS_SchedNew (void)
{ #if OS_LOWE
_PRIO <= 63u
//根据任务数是否大于64采取不同的计算方案
I
8U
y;
y
= OSUnMapTbl[OSRdyGrp];
// OSUnMapTbl可以理解为一个解码表
O
rioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);
//OSReadyTbl的大小为【OS_LOWEST_PRIO/8+1】 #else
//任务数大于64时计算优先级的方法
INT8U
y;
OS_PRIO
*ptbl;
//任务数大于64时 *ptbl是指向16位数的指针
if ((OSRdyGrp & 0xFFu) != 0u)
//有任务优先级低于64的函数就绪时那高于64的就不要计算了,算了最高优先级也不是它
{
y = OSUnMapTbl[OSRdyGrp & 0xFFu];//数字后面加u表示无符号整形
}
else
{
y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u;
}
ptbl = &OSRdyTbl[y];
//OSReadyTbl的大小为【OS_LOWEST_PRIO/16+1】与任务数小于64时不同
if ((*ptbl & 0xFFu) != 0u)
{
OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]);
}
else
{
OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u);
} #endif } 补上详细的计算方法:
1.任务数小于64的情况
先明确几个变量的作用
1.(u8)
OSRdyGrp:每一个bit代表一个组,一共8组,每组管理8个任务(具体哪一个记录在
OSRdyTbl中
)。
2.(u8)
OSPrioHighRdy:格式与
OS_PRIO相同,记录当前最高优先级任务的优先级。
3.(u8)OS_PRIO:来自
EVENT C
TROL BLOCK(事件控制块)用来记录任务优先级,与优先级一对一关系。
4.(u8)
OSReadyTbl:就绪表啦!按bit排就是下面的样子。
当一个任务就绪时,必须在0SRdyGrp和OSRdyTbl中标记,标记方法如下。
OSRdyGrp|=OSMapTbl[OS_PRIO>>3] //记录组就绪标志
//OS_PRIO的yyy有2^3种取法,记录组号TBL[yyy](就绪表第几行)
OSRdyTbl[prio>>3]|= OSMapTbl[OS_PRIO&0x07]//在TBL[yyy]上记录列就绪标志(在就绪表中写就绪标志)
//
OS_PRIO&0x07就是XXX。
OSMapTbl[OS_PRIO&0x07]把XXX转换为位掩码
OSMapTbl数组如下
OSMapTbl[8]={00000001,00000010,00000100,00001000,00010000,00100000,01000000,10000000}
这个数组就是把XXX或YYY转换为上面格式,用来给
OSRdyGrp,
TBL[yyy]
的特定bit置1。