这是一张神奇的表格.... 没搞太明白直接用了
unsigned char const DCOS_UnMapTbl[]={
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 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 */
};
INT8U DCOS_RdyGrp; //任务就绪组,其每一位对应任务就绪表的一行
INT8U DCOS_RdyTbl[8];
//任务就绪表,一共64个位,代表64个任务,位置1则代表任务就绪
INT8U DCOS_MapTbl[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
/*****************************************************************
寻找高优先级任务,进行任务调度
通过DCOS_UnMapTbl,找出当前就绪的最高优先级任务
*****************************************************************/
void DCOS_SchedNew()
{
INT8U y;
y = DCOS_UnMapTbl[DCOS_RdyGrp];
DCOS_PrioHighRdy = (INT8U)((y<<3) + DCOS_UnMapTbl[DCOS_RdyTbl[y]]);
}
//*************************以下三个函数进行任务调度***************************************
/*******************用在任务开始时调度第一个任务************
**************************************************/
void DCOS_Start()
{
if(DCOS_Running == DCOS_RUNING_F)
{
DCOS_SchedNew();
//找到当前最高优先级任务
DCOS_PrioCur = DCOS_PrioHighRdy;
//记录当前最高优先级
DCOS_TCBHighRdy = DCOS_TCBPrioTbl[DCOS_PrioHighRdy];
//从任务优先级指针数组中取出当前最高优先级的任务控制块
DCOS_OSTCBCur = DCOS_TCBHighRdy;
//将当前任务控制块指针指向当前最高优先级控制块
DCOSStartHighRdy();
//进行任务调度
}
}
/********在中断中进行任务调度**************
用在TimeTick后面,切入当前就绪的最高优先级的任务
真实uc中含有调度锁的判断,此处精简
**************************************************/
void DCOS_IntExit() //任务切换函数
{
DCOS_CPU_SR cpu_sr;
if(DCOS_Running == DCOS_RUNING_T)
//确定操作系统开启
{
DCOS_ENTER_CRITICAL();
//进入临界区
if(DCOS_IntNesting > 0)
//减少嵌套层数
{
DCOS_IntNesting--;
}
if(DCOS_IntNesting == 0)
//确定不在中断中(此函数在中断服务程序最后)
{
DCOS_SchedNew();
//寻找当前最高优先级
if(DCOS_PrioHighRdy != DCOS_PrioCur) //如果当前最高优先级不等于当前优先级
{
//注.当前优先级在底层汇编中赋值
DCOS_TCBHighRdy = DCOS_TCBPrioTbl[DCOS_PrioHighRdy]; //从任务控制块指针数组中找到此控制块
DCOSIntCtxSw();
//切任务
}
}
DCOS_EXIT_CRITICAL();
//出临界区
}
}
/**********************任务中调度函数**********************
**********************************************************/
void DCOS_Sched()
{
DCOS_CPU_SR cpu_sr;
DCOS_ENTER_CRITICAL();
if (DCOS_IntNesting == 0u)
{
DCOS_SchedNew();
DCOS_TCBHighRdy = DCOS_TCBPrioTbl[DCOS_PrioHighRdy];
if(DCOS_PrioHighRdy != DCOS_PrioCur)
{
DCOSCtxSw();
}
}
DCOS_EXIT_CRITICAL();
}