微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > μC/OS-II的任务之间的通讯与同步

μC/OS-II的任务之间的通讯与同步

时间:10-08 来源:互联网 点击:

件,该事件等待任务列表中的最高优先级任务(HighestPriorityTask–HPT)要置于就绪态时,该事件对应的OSSemPost(),OSMboxPost(),OSQPost(),和OSQPostFront()函数调用OSEventTaskRdy()实现该操作。换句话说,该函数从等待任务队列中删除HPT任务(HighestPriorityTask),并把该任务置于就绪态。图F6.4给出了OSEventTaskRdy()函数最开始的4个动作。

该函数首先计算HPT任务在.OSEventTbl[]中的字节索引[L6.6/F6.4(1)],其结果是一个从0到OS_LOWEST_PRIO/8+1之间的数,并利用该索引得到该优先级任务在.OSEventGrp中的位屏蔽码[L6.6/F6.4(2)](从表T6.1可以得到该值)。然后,OSEventTaskRdy()函数判断HPT任务在.OSEventTbl[]中相应位的位置[L6.6/F6.4(3)], 其结果是一个从0到OS_LOWEST_PRIO/8+1

之间的数,以及相应的位屏蔽码[L6.6/F6.4(4)]。根据以上结果,OSEventTaskRdy()函数计算

出HPT任务的优先级[L6.6(5)],然后就可以从等待任务列表中删除该任务了[L6.6(6)]。

任务的任务控制块中包含有需要改变的信息。知道了HPT任务的优先级,就可以得到指向该任务的任务控制块的指针[L6.6(7)]。因为最高优先级任务运行条件已经得到满足,必须停止OSTimeTick()函数对.OSTCBDly域的递减操作,所以OSEventTaskRdy()直接将该域清澈0[L6.6(8)]。因为该任务不再等待该事件的发生,所以OSEventTaskRdy()函数将其任务控制块中指向事件控制块的指针指向NULL[L6.6(9)]。如果OSEventTaskRdy()是由OSMboxPost()或者OSQPost()调用的,该函数还要将相应的消息传递给HPT,放在它的任务控制块中[L6.6(10)]。

另外,当OSEventTaskRdy()被调用时,位屏蔽码msk作为参数传递给它。该参数是用于对任务控制块中的位清零的位屏蔽码,和所发生事件的类型相对应[L6.6(11)]。最后,根据.OSTCBStat判断该任务是否已处于就绪状态[L6.6(12)]。如果是,则将HPT插入到μC/OS-II的就绪任务列表中[L6.6(13)]。注意,HPT任务得到该事件后不一定进入就绪状态,也许该任务已经由于其它

原因挂起了。[见4.07节,挂起一个任务,OSTaskSuspend(),和4.08节,恢复一个任务,

OSTaskResume()]。

另外,.OSEventTaskRdy()函数要在中断禁止的情况下调用。

程序清单L6.6使一个任务进入就绪状态

voidOSEventTaskRdy(OS_EVENT*pevent,void*msg,INT8Umsk)

{

OS_TCB*ptcb;

INT8Ux;

INT8Uy;

INT8Ubitx;

INT8Ubity;

INT8Uprio;

y=OSUnMapTbl[pevent->OSEventGrp];(1)

bity=OSMapTbl[y];(2)

x=OSUnMapTbl[pevent->OSEventTbl[y]];(3)

bitx=OSMapTbl[x];(4)

prio=(INT8U)((y3)+x);(5)

if((pevent->OSEventTbl[y]=~bitx)==0){(6)

pevent->OSEventGrp=~bity;

}

ptcb=OSTCBPrioTbl[prio];(7)

ptcb->OSTCBDly=0;(8)

ptcb->OSTCBEventPtr=(OS_EVENT*)0;(9)

#if(OS_Q_EN(OS_MAX_QS>=2))||OS_MBOX_EN

ptcb->OSTCBMsg=msg;(10)

#else

msg=msg;

#endif

ptcb->OSTCBStat=~msk;(11)

if(ptcb->OSTCBStat==OS_STAT_RDY){(12)

OSRdyGrp|=bity;(13)

OSRdyTbl[y]|=bitx;

}

}

图F6.4使一个任务进入就绪状态——Figure6.4

6.4 使一个任务进入等待某事件发生状态,OSEventTaskWait()

程序清单L6.7是OSEventTaskWait()函数的源代码。当某个任务要等待一个事件的发生时,相应事件的OSSemPend(),OSMboxPend()或者OSQPend()函数会调用该函数将当前任务从就绪任务表中删除,并放到相应事件的事件控制块的等待任务表中。

程序清单L6.7使一个任务进入等待状态

voidOSEventTaskWait(OS_EVENT*pevent)

{

OSTCBCur->OSTCBEventPtr=pevent;(1)

if((OSRdyTbl[OSTCBCur->OSTCBY]=~OSTCBCur->OSTCBBitX)==0){(2)

OSRdyGrp=~OSTCBCur->OSTCBBitY;

}

pevent->OSEventTbl[OSTCBCur->OSTCBY]|=OSTCBCur->OSTCBBitX;(3)

pevent->OSEventGrp|=OSTCBCur->OSTCBBitY;

}

在该函数中,首先将指向事件控制块的指针放到任务的任务控制块中[L6.7(1)],接着将任务从就绪任务表中删除[L6.7(2)],并把该任务放到事件控制块的等待任务表中[L6.7(3)]。

6.5 由于等待超时而将任务置为就绪态,OSEventTO()

程序清单L6.8是OSEventTO()函数的源代码。当在预先指定的时间内任务等待的事件没有发生时,OSTimeTick()函数会因为等待超时而将任务的状态置为就绪。在这种情况下,事件的OSSemPend(),OSMboxPend()或者OSQPend()函数会调用OSEventTO()来完成这项工作。该函数负责从事件控制块中的等待任务列表里将任务删除[L6.8(1)],并把它置成就绪状态[L6

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top