UCOSII任务调度分析

忽略前期初始化等细节,从main()开始:

/**************************************************************/

int Main(int argc, char **argv)
{
 ARMTargetInit();                                                            //初始化运行环境
 OSInit();                                                                         //初始化OS
 Sem_F=OSFlagCreate(0,&err);                                     //创建信号量集
 OSTaskCreate(StartTask,(void *)0,&StartTaskStk[STACKSIZE-1],0);   //创建起始任务
 OSStart();                                                      //运行任务,在OSStart()调用StartTask()
 return 0;
}

/**************************************************************/

void StartTask(void *pdata)
{
 pdata=pdata;
 ARMTargetStart();                                               //配置和打开中断,系统时钟开始运行
   OSTaskCreate(Led1Task,(void *)s1,&Led1TaskStk[STACKSIZE-1],3);  //创建任务Led1Task  
   OSTaskCreate(Led2Task,(void *)s2,&Led2TaskStk[STACKSIZE-1],4);  //创建任务Led2Task
   OSTaskCreate(Led3Task,(void *)s3,&Led3TaskStk[STACKSIZE-1],5);  //创建任务Led3Task
   do{
   OSTaskDel(0);               //删除此任务 在OSTaskDel中调用OS_Sched将运行优先级最高的Led1Task
  
   }while(1);
}

/**************************************************************/

下面为简单起见,单独分析Led1Task
void   Led1Task(void *pdata)
{
  for(;;)
  {
 //OSFlagPend(Sem_F,(OS_FLAGS)3,OS_FLAG_WAIT_SET_ALL,0,&err); //请求信号量集的第0和第1位且都置1
   rPDATC=0x02;                               //点亮led1
   //串口打印pdata,pdata为形参,由Led1Task 创建时引入,为s1, s1定义为“led1 on”  
   Uart_Printf(pdata);                       
   OSTimeDlyHMSM(0,0,2,0);                                          //延时2秒
  }
}

此时为死循环,观察循环体内的函数,唯有从OSTimeDlyHMSM(0,0,1,0)中下手,查看OSTimeDlyHMSM源代码,可发现里面调用了OSTimeDly()

/**************************************************************/
INT8U  OSTimeDlyHMSM(INT8U hours, INT8U minutes, INT8U seconds, INT16U milli)
{
    INT32U ticks;
    INT16U loops;

¥%……%#¥&**&&%¥#¥#¥&……*

    ticks = ((INT32U)hours * 3600L + (INT32U)minutes * 60L + (INT32U)seconds) * OS_TICKS_PER_SEC
          + OS_TICKS_PER_SEC * ((INT32U)milli + 500L / OS_TICKS_PER_SEC) / 1000L;
    loops = (INT16U)(ticks / 65536L);            /* Compute the integral number of 65536 tick delays   */
    ticks = ticks % 65536L;                      /* Obtain  the fractional number of ticks             */
    OSTimeDly((INT16U)ticks);
    while (loops > 0) {
        OSTimeDly((INT16U)32768u);
        OSTimeDly((INT16U)32768u);
        loops--;
    }
    return (OS_NO_ERR);
}

这里调用了OSTimeDly ,至此,仍未发现与调度相关的内容,进一步查看OSTimeDly 源代码~

/**************************************************************/
void  OSTimeDly (INT16U ticks)
{
#¥%……&*……#¥……¥&%……*

    INT8U      y;
    if (ticks > 0) {                             /* 0 means no delay!                                  */
        OS_ENTER_CRITICAL();
  y            =  OSTCBCur->OSTCBY;      /* Delay current task                                 */
  OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0) { 
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
 /*ticks 非0值会使得任务延时函数OSTimeDly()将当前任务从就绪表中移除*/
        OSTCBCur->OSTCBDly = ticks;              /* Load ticks in TCB                                  */
        OS_EXIT_CRITICAL();
        OS_Sched();                              /* Find next task to run!                             */
    }
}

终于发现亲人了....OS_Sched ==! 此时,如果ticks大于0,则该任务被OSTimeDly 挂起,由OS_Sched 运行更低优先级的任务。此时系统中用户共创建了三个任务,比Led1Task 稍低的是Led2Task因此,系统会运行Led2Task 基于同样的调度原理,进而运行Led3Task 

然而,如果此时只有一个任务,那将会发生什么情况呢?换句话说,系统运行到OSTimeDly  时没有比当前任务优先级更低的任务时怎么办?哈哈 我们还有大招...OS_TaskIdle,OS_TaskIdle是ucosii中由OS自行创建的优先级最低的任务,且不能被用户删除。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值