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

13 篇文章 0 订阅
4 篇文章 0 订阅
这是一张神奇的表格.... 没搞太明白直接用了
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值