之前在和rawos作者的闲聊中,rawos作者认为实时操作系统中大的特色是互斥量的问题。一开始,我对这个看法其实是有保留意见的,直到我看到了修改优先级的相关代码,才开始对作者的看法有了很大的认同感。实话说,在嵌入式实时系统中修改优先级是一个很复杂的事情,为什么呢,因为这其中涉及到了互斥量的问题。我们大家都知道,在嵌入式系统中优先级反转是一个绕不去的砍。低优先级的任务因为获得了互斥量因而比高优先级的任务获得了更多的运行机会,这从根本上违背了实时系统设计的初衷。所以,人们为了解决除了这一问题,提出了优先级互斥量和优先级继承两种方法。

  优先级互斥量的办法比较简单,ucos也是这么做的。我们在分配一个互斥量的时候,也给这个互斥量分配一定的优先级。任何获得该互斥量的任务都会把自己的优先级修改为互斥量的优先级,这样保证了获得该优先级的任务可以在短的时间内完成,尽快释放资源。但是,这也会导致一个问题,那是该互斥量需要占用一个优先级,而且比此优先级高的任务也没办法获得该互斥量。另外一种方法是优先级继承的方法,简单一点说是任何对阻塞线程优先级的修改,都会导致拥有此互斥量的任务进行优先级的修改。闲话不多说,我们看看rawos上面的代码是怎么描述的,

RAW_U16 raw_task_priority_change (RAW_TASK_OBJ *task_ptr, RAW_U8 new_priority, RAW_U8 *old_priority)
{
 RAW_U8 ret_pri;
 RAW_U16 error;
 
 RAW_SR_ALLOC();

 #if (RAW_TASK_FUNCTION_CHECK > 0)
 
 if (task_ptr == 0) {
 
  return RAW_NULL_OBJECT;
 }

 if (old_priority == 0) {
 
  return RAW_NULL_OBJECT;
 }
 
 #endif 

 /*Idle task is not allowed to change priority*/
 if (task_ptr->priority >= IDLE_PRIORITY) {
 
  return RAW_CHANGE_PRIORITY_NOT_ALLOWED;
 }
 
   /*Not allowed change to idle priority*/
 if (new_priority == IDLE_PRIORITY) {           

  return RAW_CHANGE_PRIORITY_NOT_ALLOWED;
 }


 RAW_CRITICAL_ENTER();

 #if (CONFIG_RAW_MUTEX > 0)
 ret_pri = chg_pri_mutex(task_ptr, new_priority, &error);

 if (error != RAW_SUCCESS) {
  goto error_exit;
 }

 task_ptr->bpriority = new_priority;
 new_priority = ret_pri;
 
 #else
 
 task_ptr->bpriority = new_priority;
 #endif

 *old_priority = task_ptr->priority;

 error = change_interal_task_priority(task_ptr, new_priority);
 
 if (error != RAW_SUCCESS) {
  goto error_exit;
 }

 RAW_CRITICAL_EXIT();
 
 do_possible_sche();
 
  return RAW_SUCCESS;
 
 error_exit:
 RAW_CRITICAL_EXIT();
 return error;
 
}