这两个IF起什么作用啊,求大神讲解下

2019-07-14 17:46发布

最近看实时操作系统,鸟哥提问了个问题、、有处一直没理解。求大神讲解下

mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /*  Get priority of mutex owner   */
        ptcb  = (OS_TCB *)(pevent->OSEventPtr);                   /*     Point to TCB of mutex owner   */
        if (ptcb->OSTCBPrio > pcp)                                /*     Need to promote prio of owner?*/
        {
            if (mprio > OSTCBCur->OSTCBPrio)
            {
             。。。。。。     
            }
       }
谁知道这两个if起什么作用?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
9条回答
你我然后
2019-07-15 05:44
//----------------------------------------------------------------------
//4.OSMutexPost()函数
INT8U OSMutexPost (OS_EVENT *pevent)
{
    INT8U pip;
    INT8U prio;
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr = 0;//方式3将把cpsr状态寄存器推入临时堆栈cpu_sr中,可以安全返回之前的中断状态
#endif
    if (OSIntNesting > 0) {
        return (OS_ERR_POST_ISR);
    }
#if OS_ARG_CHK_EN > 0
    if (pevent == (OS_EVENT *)0) {
        return (OS_ERR_PEVENT_NULL);
    }
#endif
    if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {
        return (OS_ERR_EVENT_TYPE);
    }
    OS_ENTER_CRITICAL();
    pip = (INT8U)(pevent->OSEventCnt >> 8);//变相置顶值pip
    prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);//持有mutex资源的task原始优先级
    if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) {
//因为解决了局部优先级翻转问题,所以OSTCBCur肯定要等于pevent->OSEventPtr
//否则发生了不知名的异常
        OS_EXIT_CRITICAL();
        return (OS_ERR_NOT_MUTEX_OWNER);
    }
    if (OSTCBCur->OSTCBPrio == pip) {
//task被提升了优先级到pip置顶值,也就是一个比该task优先级高
//比pip低的进程需要访问互斥资源,即:存在B角 {MOD}进程,
//那么使用OSMutex_RdyAtPrio()把本task从就绪控制矩阵中摘下来
//同时将自己还原到prio优先级
        OSMutex_RdyAtPrio(OSTCBCur, prio);
    }
    OSTCBPrioTbl[pip] = OS_TCB_RESERVED;
    if (pevent->OSEventGrp != 0) {
    //2007-09-09 gliethttp
    //OS_EventTaskRdy()函数将摘掉等待在pevent事件控制矩阵上的task中优先级最高的task
    //如果该task仅仅等待该pevent事件,那么将该task添加到就绪控制矩阵中
    //OSRdyGrp |= bity;
    //OSRdyTbl[y] |= bitx;这样调度程序就会根据情况调度OS_Sched()该task了
        prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
    //保持处于高8位的pip置顶优先级值
    //同时清除低8位数据
        pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;
        pevent->OSEventCnt |= prio;//获得执行权的task充当优先级翻转计算中的C角 {MOD}
        pevent->OSEventPtr = OSTCBPrioTbl[prio];//task的控制块传给OSEventPtr指针,供优先级翻转计算使用
        if (prio <= pip) {
//2007-09-09 gliethttp
//prio比pip小,那么说明比置顶值pip优先级还要高的进程竟然访问了共享资源,
//那么这时可能会出现优先级翻转,因为这时mutex机制已经不起作用,
//所以应该保证"变相置顶的方式"初始化时,自己内定的最高优先级pip务必大于所有能访问互斥资源的进程优先级[gliethttp]
            OS_EXIT_CRITICAL();
            OS_Sched();//具体参见《浅析μC/OS-II v2.85内核调度函数》
            return (OS_ERR_PIP_LOWER);
        } else {
            OS_EXIT_CRITICAL();
            OS_Sched();//具体参见《浅析μC/OS-II v2.85内核调度函数》
            return (OS_ERR_NONE);
        }
    }
    //没有任何一个task悬停在本event事件控制矩阵上[gliethttp]
    pevent->OSEventCnt |= OS_MUTEX_AVAILABLE;//还原为初始值
    pevent->OSEventPtr = (void *)0;//现在本task不悬停在任何event事件上
    OS_EXIT_CRITICAL();
    return (OS_ERR_NONE);
}
//----------------------------------------------------------------------
//5.OS_EventTaskRdy()函数
INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *pmsg, INT8U msk, INT8U pend_stat)
{
    OS_TCB *ptcb;
    INT8U x;
    INT8U y;
    INT8U prio;
#if OS_LOWEST_PRIO <= 63
    INT8U bitx;
    INT8U bity;
#else
    INT16U bitx;
    INT16U bity;
    INT16U *ptbl;
#endif

#if OS_LOWEST_PRIO <= 63
//小于64个task时,快速计算
//最有优先权的task位于事件控制矩阵中的第y行的第x列
    y = OSUnMapTbl[pevent->OSEventGrp];
    bity = (INT8U)(1 << y);
    x = OSUnMapTbl[pevent->OSEventTbl[y]];
    bitx = (INT8U)(1 << x);
    prio = (INT8U)((y << 3) + x);
#else
//对于256个task
//最有优先权的task位于事件控制矩阵中的第y行的第x列
//以下的操作原理具体参见《浅析μC/OS-II v2.85内核调度函数》
    if ((pevent->OSEventGrp & 0xFF) != 0) {
        y = OSUnMapTbl[pevent->OSEventGrp & 0xFF];
    } else {
        y = OSUnMapTbl[(pevent->OSEventGrp >> 8) & 0xFF] + 8;
    }
    bity = (INT16U)(1 << y);
    ptbl = &pevent->OSEventTbl[y];
    if ((*ptbl & 0xFF) != 0) {
        x = OSUnMapTbl[*ptbl & 0xFF];
    } else {
        x = OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8;
    }
    bitx = (INT16U)(1 << x);
    prio = (INT8U)((y << 4) + x);//该task对应的prio优先级值
//ok,等待在event事件上的所有task中,只有在事件控制矩阵中的第y行的第x列task
//优先级最高、最值的成为此次事件的唤醒对象[gliethttp]
#endif
//清除此task在event事件控制矩阵中的bit位
    pevent->OSEventTbl[y] &= ~bitx;
    if (pevent->OSEventTbl[y] == 0) {
        pevent->OSEventGrp &= ~bity;
    }
//通过prio优先级找到该prio唯一对应的task对应的ptcb进程上下文控制块
    ptcb = OSTCBPrioTbl[prio];
    ptcb->OSTCBDly = 0;//复原为正常
    ptcb->OSTCBEventPtr = (OS_EVENT *)0;//现在本task不悬停在任何event事件上
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
    ptcb->OSTCBMsg = pmsg;//传递消息指针
#else
    pmsg = pmsg;
#endif
    ptcb->OSTCBStatPend = pend_stat;//悬停状态值
    ptcb->OSTCBStat &= ~msk;//该msk事件已经发生,清除task上下文控制块上的msk位,如:OS_STAT_MUTEX
    if (ptcb->OSTCBStat == OS_STAT_RDY) {
    //如果当前task只是等待该事件,那么把该task放到就绪控制矩阵中,允许内核调度本task
        OSRdyGrp |= bity;
        OSRdyTbl[y] |= bitx;
    }
    return (prio);//返回本task对应的优先级值
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PS:"所以从这里来看,os中的各个功能单元管理着自己的事情,就像面向对象的封装一样,"
   "事件控制矩阵和就绪控制矩阵是各个对象独立自治的关键因素"
   "其他对象,都努力说服自己相信别的对象是独立的、可信任的、安全的"[gliethttp]
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

一周热门 更多>