[求助] ucos源码一个函数,恳请大神帮忙分析下~~~

liuchang---   2015-7-13 08:59 楼主
如下这个是ucos_iii的源码---改变任务优先级函数,大神能在下面的几个地方给小弟讲解一下吗?感谢了~~~                    
void  OSTaskChangePrio (OS_TCB   *p_tcb,
                        OS_PRIO   prio_new,
                        OS_ERR   *p_err)
{
    CPU_BOOLEAN   self;
    CPU_SR_ALLOC();           /*问题1:将CPU状态寄存器的值保存起来,我想问:什么时候需要保存这个值?每次调用函数都需要?*/

#ifdef OS_SAFETY_CRITICAL/*问题2:这段代码是什么意思?我找不到它的定义~~~*/
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u/*问题3:不能在ISR中创建一个任务,那在中断中具体可以做些什么呢?*/
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {            
       *p_err = OS_ERR_TASK_CHANGE_PRIO_ISR;
        return;
    }
#endif

    if (prio_new >= (OS_CFG_PRIO_MAX - 1u)) {            
        *p_err = OS_ERR_PRIO_INVALID;
        return;
    }

    if (p_tcb == (OS_TCB *)0) {                       /*问题4:这个任务控制块的指针指向空时啥意思?我看源码上的注释是"self",为什么这样就是指向自己呢?*/
        CPU_CRITICAL_ENTER();
        p_tcb = OSTCBCurPtr;
        CPU_CRITICAL_EXIT();
        self  = DEF_TRUE;
    } else {
        self  = DEF_FALSE;
    }

    OS_CRITICAL_ENTER();
    switch (p_tcb->TaskState) {                       
        case OS_TASK_STATE_RDY:                        
             OS_RdyListRemove(p_tcb);                     
             p_tcb->Prio = prio_new;                  
             OS_PrioInsert(p_tcb->Prio);
             if (self == DEF_TRUE) {
                 OS_RdyListInsertHead(p_tcb);
             } else {
                 OS_RdyListInsertTail(p_tcb);
             }
             break;

        case OS_TASK_STATE_DLY:                          
        case OS_TASK_STATE_SUSPENDED:
        case OS_TASK_STATE_DLY_SUSPENDED:
             p_tcb->Prio = prio_new;                  
             break;

        case OS_TASK_STATE_PEND:
        case OS_TASK_STATE_PEND_TIMEOUT:
        case OS_TASK_STATE_PEND_SUSPENDED:
        case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
             switch (p_tcb->PendOn) {                     
                 case OS_TASK_PEND_ON_TASK_Q:              
                 case OS_TASK_PEND_ON_TASK_SEM:
                 case OS_TASK_PEND_ON_FLAG:
                      p_tcb->Prio = prio_new;              
                      break;

                 case OS_TASK_PEND_ON_MUTEX:
                 case OS_TASK_PEND_ON_MULTI:
                 case OS_TASK_PEND_ON_Q:
                 case OS_TASK_PEND_ON_SEM:
                      OS_PendListChangePrio(p_tcb,
                                            prio_new);
                      break;

                 default:
                      break;
            }
             break;

        default:
             OS_CRITICAL_EXIT();
             *p_err = OS_ERR_STATE_INVALID;
             return;
    }

    OS_CRITICAL_EXIT_NO_SCHED();

    OSSched();                                             

    *p_err = OS_ERR_NONE;
}
#endif



回复评论 (5)

没看懂……帮顶
点赞  2015-7-13 09:25
  1. void  OSTaskChangePrio (OS_TCB   *p_tcb,OS_PRIO   prio_new,OS_ERR   *p_err)
  2. {
  3.     CPU_BOOLEAN   self;
  4.     CPU_SR_ALLOC();           /*问题1:将CPU状态寄存器的值保存起来,我想问:什么时候需要保存这个值?每次调用函数都需要?*/

  5. #ifdef OS_SAFETY_CRITICAL/*问题2:这段代码是什么意思?我找不到它的定义~~~*/
  6.     if (p_err == (OS_ERR *)0) {
  7.         OS_SAFETY_CRITICAL_EXCEPTION();
  8.         return;
  9.     }
  10. #endif

  11. #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u/*问题3:不能在ISR中创建一个任务,那在中断中具体可以做些什么呢?*/
  12.     if (OSIntNestingCtr > (OS_NESTING_CTR)0) {            
  13.        *p_err = OS_ERR_TASK_CHANGE_PRIO_ISR;
  14.         return;
  15.     }
  16. #endif

  17.     if (prio_new >= (OS_CFG_PRIO_MAX - 1u)) {            
  18.         *p_err = OS_ERR_PRIO_INVALID;
  19.         return;
  20.     }

  21.     if (p_tcb == (OS_TCB *)0) {                       /*问题4:这个任务控制块的指针指向空时啥意思?我看源码上的注释是"self",为什么这样就是指向自己呢?*/
  22.         CPU_CRITICAL_ENTER();
  23.         p_tcb = OSTCBCurPtr;
  24.         CPU_CRITICAL_EXIT();
  25.         self  = DEF_TRUE;
  26.     } else {
  27.         self  = DEF_FALSE;
  28.     }

  29.     OS_CRITICAL_ENTER();
  30.     switch (p_tcb->TaskState) {                       
  31.         case OS_TASK_STATE_RDY:                        
  32.              OS_RdyListRemove(p_tcb);                     
  33.              p_tcb->Prio = prio_new;                  
  34.              OS_PrioInsert(p_tcb->Prio);
  35.              if (self == DEF_TRUE) {
  36.                  OS_RdyListInsertHead(p_tcb);
  37.              } else {
  38.                  OS_RdyListInsertTail(p_tcb);
  39.              }
  40.              break;

  41.         case OS_TASK_STATE_DLY:                          
  42.         case OS_TASK_STATE_SUSPENDED:
  43.         case OS_TASK_STATE_DLY_SUSPENDED:
  44.              p_tcb->Prio = prio_new;                  
  45.              break;

  46.         case OS_TASK_STATE_PEND:
  47.         case OS_TASK_STATE_PEND_TIMEOUT:
  48.         case OS_TASK_STATE_PEND_SUSPENDED:
  49.         case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
  50.              switch (p_tcb->PendOn) {                     
  51.                  case OS_TASK_PEND_ON_TASK_Q:              
  52.                  case OS_TASK_PEND_ON_TASK_SEM:
  53.                  case OS_TASK_PEND_ON_FLAG:
  54.                       p_tcb->Prio = prio_new;              
  55.                       break;

  56.                  case OS_TASK_PEND_ON_MUTEX:
  57.                  case OS_TASK_PEND_ON_MULTI:
  58.                  case OS_TASK_PEND_ON_Q:
  59.                  case OS_TASK_PEND_ON_SEM:
  60.                       OS_PendListChangePrio(p_tcb,
  61.                                             prio_new);
  62.                       break;

  63.                  default:
  64.                       break;
  65.             }
  66.              break;

  67.         default:
  68.              OS_CRITICAL_EXIT();
  69.              *p_err = OS_ERR_STATE_INVALID;
  70.              return;
  71.     }

  72.     OS_CRITICAL_EXIT_NO_SCHED();

  73.     OSSched();                                             

  74.     *p_err = OS_ERR_NONE;
  75. }
  76. #endif
点赞  2015-7-13 09:38
帮你调整一下对齐。但是感觉怎么多了一个endif?
点赞  2015-7-13 09:40
哦,多了一个endif是因为
#if OS_CFG_TASK_CHANGE_PRIO_EN > 0u
#endif
这个我没加上
点赞  2015-7-13 13:01
哪位大神不惜赐教,帮我分析下这段代码,感激万分~~~
点赞  2015-7-13 13:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复