优先级反转及ucos对该情况的处理

在这里插入图片描述
如图所示,三个任务L,M,H,

中等优先级的任务M抢占cpu,已获取信号量的低优先级任务L无法执行并释放信号量,导致等待信号量而阻塞的高优先级任务H必须等中等任务M释放CPU而使L任务执行释放信号量才可继续执行,从用户宏观使用角度来看,任务M运行优先级似乎比任务H还要高,这就是优先级反转。

优先级提权
ucos解决方法就是占用信号量的任务的优先级会根据当前任务的高低而进行是否提权,
上图例子在ucos中,(5)步,H任务因无法等待信号量而阻塞后,会将已获取信号量的任务L优先级暂时提权为与H优先级一致,直到释放信号量,因此M任务无法打断L任务,从而避免了优先级反转的情况。

OSMutexPend处理优先级反转逻辑节选

   OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();                  /* 关中断                */
    p_tcb = p_mutex->OwnerTCBPtr;                           /* 占用信号量的任务通常把指针                  */
    if (p_tcb->Prio > OSTCBCurPtr->Prio) {                  /*信号量拥有者的任务优先级低于当前任务  */
        switch (p_tcb->TaskState) {
            case OS_TASK_STATE_RDY:
                 OS_RdyListRemove(p_tcb);                   /* Remove from ready list at current priority             */
                 p_tcb->Prio = OSTCBCurPtr->Prio;           /*运行态 提权                               */
                 OS_PrioInsert(p_tcb->Prio);
                 OS_RdyListInsertHead(p_tcb);               /* Insert in ready list at new priority                   */
                 break;

            case OS_TASK_STATE_DLY:
            case OS_TASK_STATE_DLY_SUSPENDED:
            case OS_TASK_STATE_SUSPENDED:
                 p_tcb->Prio = OSTCBCurPtr->Prio;           /* 挂起仅改优先级即可               */
                 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:
                 OS_PendListChangePrio(p_tcb,  
                                       OSTCBCurPtr->Prio);
                 break;

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

OSMutexPost处理优先级反转逻辑节选

 if (OSTCBCurPtr->Prio != p_mutex->OwnerOriginalPrio) {   //优先级不等于原始优先级,原始优先级在申请到信号量后更新
        OS_RdyListRemove(OSTCBCurPtr);
        OSTCBCurPtr->Prio = p_mutex->OwnerOriginalPrio;     /* 恢复优先级*/
        OS_PrioInsert(OSTCBCurPtr->Prio);
        OS_RdyListInsertTail(OSTCBCurPtr);        
        OSPrioCur         = OSTCBCurPtr->Prio;
    }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值