自己仿写一个ucosii(四) 任务调度函数

来源:互联网 发布:金锐盘开票软件 编辑:程序博客网 时间:2024/05/02 02:52
这是一张神奇的表格.... 没搞太明白直接用了
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();


}
2 0
原创粉丝点击