通过的上面的代码,我们可以看到其实系统啥也没干,只是把任务方法放到优先级的链表末尾了。因为我们的系统需要实时调度,所以即使把使用权出让出来,也不可能让低优先的任务运行,只能让同优先级的其他任务运行了。当然,同优先级没有其他任务的时候,只好它自己继续玩了。说了这么多,我们看看系统是怎么调度的,

void raw_sched()
 {
  RAW_SR_ALLOC();
 
  /*if it is in interrupt or system is locked, just return*/
  if (raw_int_nesting || raw_sched_lock) {             
      return;                                            
  }
  
  RAW_CRITICAL_ENTER();
              
  
  get_ready_task(&raw_ready_queue);
 
  /*if highest task is currently task, then no need to do switch and just return*/
  if (high_ready_obj == raw_task_active) {                
      RAW_CRITICAL_EXIT();                                    
      return;
  }
  
  CONTEXT_SWITCH();                                          
  RAW_CRITICAL_EXIT();
 
 }

  这个函数看上去很长,其实重要的部分是get_ready_task这个函数,它的目的是寻找到当前高优先级下面的任务,大家看看代码明白了,

 void get_ready_task(RAW_RUN_QUEUE *rq)
 {
  LIST *node ;
  RAW_S32 highest_pri =  rq->highest_priority;
  /*Highest task must be the first element on the list*/
  node = rq->task_ready_list[highest_pri].next;
 
  high_ready_obj = list_entry(node, RAW_TASK_OBJ, task_list);
  
 }

  所以,实时系统的核心是寻找到那个高优先级可以了。在实时系统上面,我们一般用bitmap表示优先级,如果对应的优先级存在,那么该位置1,反之置0。那么什么情况下,会发生优先级的改变呢?其实两种情况,一种是需要把任务加入调度队列的时候,还有一种是把任务清除出调度队列的时候。

void add_ready_list(RAW_RUN_QUEUE *rq, RAW_TASK_OBJ *task_ptr)
 {
  /*if task priority is equal current task priority then add to the end*/
  if (task_ptr->priority == raw_task_active->priority) {
   add_ready_list_end(rq, task_ptr);
  }
  /*if not add to the list front*/
  else {
   add_ready_list_head(rq, task_ptr);
  }
  
 }
 
 
 void remove_ready_list(RAW_RUN_QUEUE *rq, RAW_TASK_OBJ *task_ptr)
 {
 
  RAW_S32  i;
  RAW_S32  priority = task_ptr->priority;
 
  list_delete(&task_ptr->task_list);
 
  /*if the ready list is not empty, we do not need to update the highest priority*/
  if (!is_list_empty(&rq->task_ready_list[priority]) ) {
   return;
  }
 
  bit_clear(rq->task_bit_map, priority);
 
  /*If task priority not equal to the highest priority, then we do not need to update the highest priority*/
  if (priority != rq->highest_priority) {
   return;
  }
  
  i =  bit_search_first_one(rq->task_bit_map, priority,  CONFIG_RAW_PRIO_MAX - priority);
  /*Update the next highest priority task*/
  if (i >= 0) {
   rq->highest_priority = priority + i;
  }
 
  else {
   
   #if (CONFIG_RAW_ASSERT > 0)
   RAW_ASSERT(0);
   #endif
 
  }
  
 }