原创 调度器

2011-3-14 09:57 5293 9 9 分类: 电源/新能源

调度器的核心是调度器数据结构。这是一种用户自定义的数据类型,集中了每个任务所需的信息。

typedef data struct //可能的话,存储在DATA区,速度快,每个任务7个字节。
{
    void (code *pTask)(void);   //指向任务的指针(必须是一个" void(void)"函数)
 ushort Delay;  //延迟直到下一次执行
 ushort Period;  //连续运行时间间隔
 ushort RunMe;  //当任务需要运行时,由调度器加1
 uchar  Co_op;//如果任务是合作式的,设置为1,如果任务是抢占式的,设置为0
}sTask;
sTask SCH_tasks_G[SCH_MAX_TASKS];

tByte SCH_Add_Task(void (code * pFunction)(),
                   const tWord DELAY,
                   const tWord PERIOD)   
   {
   tByte Index = 0;
   //首先在队列中找一个空隙,如果有的话
      while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
      {
      Index++;
      }
  
   // 是否到达结尾   
   if (Index == SCH_MAX_TASKS)
      {
      // 队列已满   

   //设置全局错误变量
         Error_code_G = ERROR_SCH_TOO_MANY_TASKS;

      // Also return an error code
      return SCH_MAX_TASKS; 
      }
 //如果能运行到这里,则说明任务队列中有空位     
    SCH_tasks_G[Index].pTask  = pFunction;     
   SCH_tasks_G[Index].Delay  = DELAY;
   SCH_tasks_G[Index].Period = PERIOD;

   SCH_tasks_G[Index].RunMe  = 0;

   return Index; // return position of task (to allow later deletion)
   }

当任务被添加到任务队列时,SCH_Add_Task()返回该任务在任务队列中的位置:

Task_ID=SCH_Add_Task();

有时需要从队列中删除任务,可以如下使用SCH_Delet_Task();来实现

SCH_Delete_Task( TASK_ID) ;

bit SCH_Delete_Task(const tByte TASK_INDEX)
   {
   bit Return_code;

   if (SCH_tasks_G[TASK_INDEX].pTask == 0)
      {
      // No task at this location...
      //
      // Set the global error variable
      Error_code_G = ERROR_SCH_CANNOT_DELETE_TASK;

      // ...also return an error code
      Return_code = RETURN_ERROR;
      }
   else
      {
      Return_code = RETURN_NORMAL;
      }     
  
   SCH_tasks_G[TASK_INDEX].pTask   = 0x0000;
   SCH_tasks_G[TASK_INDEX].Delay   = 0;
   SCH_tasks_G[TASK_INDEX].Period  = 0;

   SCH_tasks_G[TASK_INDEX].RunMe   = 0;

   return Return_code;       // return status
   }

void SCH_Go_To_Sleep()
   {
   PCON |= 0x01;    // Enter idle mode (generic 8051 version)

   // Entering idle mode requires TWO consecutive instructions
   // on 80c515 / 80c505 - to avoid accidental triggering
   //PCON |= 0x01;    // Enter idle mode (#1)
   //PCON |= 0x20;    // Enter idle mode (#2)
   }每次调用调度程序的结尾将系统置为“睡眠”,并在下一个定时器时标产生时醒来

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条