首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ucos互斥信号量(2)

ucos互斥信号量(2)

//信号量不可用:即已被占用
//从该信号量中获得PIP
pip   = (INT8U)(pevent->OSEventCnt >> 8);
//从该信号量中获得占用该信号量的任务的优先级。                    
mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  
//从信号量中获得占用该信号量的任务
ptcb  = (OS_TCB *)(pevent->OSEventPtr);  

/*
     如果原先占用该mutex的优先级比提出申请该mutex的任务的优先级低
    (mprio > OSTCBCur->OSTCBPrio),则提升原任务的优先级至PIP
*/
    if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) {  
        if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) {     
            if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
                OSRdyGrp &= ~ptcb->OSTCBBitY;
            }
            //若原任务已就绪,则将其从就绪表中删除,并置就绪标志rdy
            rdy = TRUE;
        } else {
            rdy = FALSE;                                          
        }
        //修改优先级,及相关参数
        ptcb->OSTCBPrio  = pip;                     
        ptcb->OSTCBY    = ptcb->OSTCBPrio >> 3;
        ptcb->OSTCBBitY  = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX     = ptcb->OSTCBPrio & 0x07;
        ptcb->OSTCBBitX   = OSMapTbl[ptcb->OSTCBX];

        //如果原任务是就绪的,则继续让新的优先级就绪
        if (rdy == TRUE) {                                
            OSRdyGrp               |= ptcb->OSTCBBitY;   
            OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        }
        OSTCBPrioTbl[pip]   = (OS_TCB *)ptcb;
}
//让提出申请的任务先等待(从就绪表中删除,如mutex的等待队列)………
    OSTCBCur->OSTCBStat |= OS_STAT_MUTEX;            
    OSTCBCur->OSTCBDly   = timeout;                  
    OS_EventTaskWait(pevent);  
OS_EXIT_CRITICAL();
//执行任务切换(如果原来低优先级的任务优先级被抬高了,则该任务将被执行)
    OS_Sched();                                       
OS_ENTER_CRITICAL();
//提出申请的任务被唤醒继续执行
if (OSTCBCur->OSTCBStat & OS_STAT_MUTEX) {
    //1)由于等待超时被定时器唤醒        
        OS_EventTO(pevent);
        OS_EXIT_CRITICAL();
        *err = OS_TIMEOUT;                           
        return;
}
/*
      2)原先占用mutex的任务执行完成释放了mutex
         并唤醒了等待该mutex的最高优先级的任务
*/
    OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
    OS_EXIT_CRITICAL();
    *err = OS_NO_ERR;
}


释放一个互斥信号量:OSMutexPost()
关键代码剖析:
INT8U  OSMutexPost (OS_EVENT *pevent)
{
   //不得在中断中调用该函数
    if (OSIntNesting > 0) {                           
        return (OS_ERR_POST_ISR);                    
    }
OS_ENTER_CRITICAL();
继承事业,薪火相传
返回列表