任务创建是基于一个有序表。这种方法虽然简单直观,但也有很大缺点。比如如果建立了100个任务,又准备建立第101个任务,且第101个任务优先级是高的。那么创建任务很慢,需要前面一百个任务依次都向后移,第101个任务放在数组的前面。这是十分耗时的操作,随着任务数的增加,创建任务的时间也随着增加。后面还要讲到,这种方法建立的任务查找高优先级时,需要遍历数组,在效率上也是不快的,尤其是任务数目多时。任务创建之后,接下来的事情是何时需要任务切换,如何查找高优先级了。先说下何时需要任务切换,每个任务都是一个while(1)死循环,在里面执行到OSTimedly()时会挂起当前任务,查找高优先级的任务。每个任务的控制块中都有个延时时间的变量,当这个延时时间变量大于0,说明这个任务还处于睡眠或挂起状态,不能够被执行。因此还需要一个系统时钟函数,作为整个系统的调度中心,每到一个系统时钟中断,让所有任务的延时时间减一。

/*
 *系统时钟函数,在时钟中断中调用
*/
void  OSTimeTick (void)
{
    int8 index;
    TCB  *pTCB;
    uint8 flagFirstTask=0;
    OS_CPU_SR  cpu_sr = 0;
    OS_ENTER_CRITICAL();
    /*初始化*/
    OSNewTCB = NULL;
 /*禁止调度*/
    if (OSScheLock != 0)
    {
       OS_EXIT_CRITICAL();
       return;
    }
 for (index = 0;index < TaskNUM;index++)
 {
     pTCB = OSTCBTable+index;
    /*该任务在睡眠状态,必须将所有时延都--*/
     if (pTCB->TCBDelay > 0)
     {
        pTCB->TCBDelay--;
        continue;
     }
     /*该任务被挂起*/
     if (pTCB->TaskStat == OS_Task_Pend)
     {
         continue;
     }
    /*任务优先级查找算法,以后考虑改进查找速度*/
   /* 是否找到了应该调度进去的绪任务*/
  if (flagFirstTask==0)
  {
   /*找到了高优先级的任务,
     并且比当前任务优先级高*/
     if (OSCurTCB->CurPriority < pTCB->CurPriority)
     {
        flagFirstTask = 1;
        OSNewTCB = pTCB;
        continue;
     }
    /*找到了比当前优先级低的任务*/
    if (OSCurTCB->CurPriority > pTCB->CurPriority)
   {
       if (OSNewTCB == NULL)
      {
          flagFirstTask = 1;
          OSNewTCB = pTCB;
          continue  ;
      }
      else
     {
         flagFirstTask = 1;
        continue  ;
      }
   }
 
   /*找到了高优先级的任务,
     并且跟当前任务优先级相等*/
   if (OSCurTCB->CurPriority == pTCB->CurPriority)
   {
    /*该任务在当前任务之后*/
    if ((pTCB > OSCurTCB)||(pTCB == OSCurTCB))
    {
     flagFirstTask = 1;
     OSNewTCB = pTCB;
     continue  ;
    }
    /*在当前任务之前或者是当前任务
      则还需要继续向后搜索第一个同优先级的任务*/
    if ((pTCB < OSCurTCB)&&(OSNewTCB == NULL))
    {
      OSNewTCB = pTCB;
      continue;
    }
   }
   continue;
  }
 
 }
 OS_EXIT_CRITICAL();
}

   在时钟中断里,需要调用这个函数,这个函数的作用很简单,一方面让每个任务的延时时间减一,一方面查找高优先级的任务,找到了高优先级的任务时,把 OSNewTCB = pTCB;把高优先级的任务堆栈指针赋给 OSNewTCB 。

void SysTick_Handler(void)
{
 OSIntEnter();  //进入中断
 OSTimeTick();
 OSIntExit();        //触发任务切换软中断
}

/*
*记录中断嵌套层数
*/
void  OSIntEnter (void)
{
    if (NULL != OSCurTCB)
   {
        if (OSIntNesting < 255u)
        {
            OSIntNesting++;                      /* Increment ISR nesting level                        */
        }
    }
}

/*
*中断退出时调用,触发中断级任务切换
*/
void  OSIntExit (void)
{
     OS_CPU_SR  cpu_sr = 0u;
    if (NULL!= OSCurTCB)
    {
        OS_ENTER_CRITICAL();
        if (OSIntNesting > 0u)
        {                         
            OSIntNesting--;
        }
        if (OSIntNesting == 0u)
        {                        
            /* 当所有的中断完成候再判断是否调度  */
            if (OSNewTCB != OSCurTCB)
            {
              /* 中断级任务切换  */
              OSIntCtxSw();  
            }
        }
        OS_EXIT_CRITICAL();
    }
}