为了把描述事件的数据结构统一起来,ucosii使用了事件控制块ECB的数据结构来描述诸如信号
量、邮箱、消息队列等事件。
任务或中断服务子程序可以通过事件控制块ECB来向另外的任务发信号。
用于通信的数据结构叫事件控制块。
对事件控制块操作的函数有4个:(XXX为信号量,邮箱或消息队列等)
事件控制块初始化函数OS_EventWaitListInit(),该函数被OSXXXCreate()调用。
使一个任务进入等待状态函数OS_EventTaskWait(), 该函数被OSXXXPend()调用。
使一个任务进入就绪态函数OS_EventTaskRdy(),该函数被OSXXXPost()调用。
使一个等待超时的任务进入就绪态的函数OS_EventTo(), 该函数被OSXXXPend()调用。
信号量
信号量由信号计数器和任务等待表两部分组成。
使用事件控制块成员OSEventCnt来做为计数器,OSEventTbl[]数组来充当等待任务表。
信号量不使用*OSEventPtr
当一个任务需要访问共享资源时,先要请求管理该资源的信号量,根据信号量是否有效来决定该任
务是否运行,如果该信号量有效(即OSEventCnt大于0),则把信号量减一,继续运行该任务;当
信号量无效时,则会在等待任务表中把该任务对应为置一使该任务处于等待状态,并把等待时限
timeout保存在TCB的OSTCBDly中。
释放信号量也叫发送信号量,前者更容易理解。
函数OSSemPost()在对信号量计数器操作之前,检查是否有任务等待信号量,如果没有把信号量
计数器OSEventCnt加一,如果有则调用 调度器OS_Sched()去运行等待任务中优先级最高的任
务。
OSSemPend()与OSSemPost()一般成对出现。
只有在任务中删除信号量不能在中断服务程序中删除信号量。
互斥型信号量
互斥型信号量为二值信号,可以使任务以独占方式共享资源。
互斥型信号量也不使用*OSEventPtr
ECB成员OSEventCnt被分为低八位和高八位两部分,低八位用来存放信号值(该值为0xFF有效),
高八位用来存放为了避免出现优先级反转现象为提升优先级的prio.
提升优先级的是得到该互斥型信号量的任务。
消息邮箱
消息邮箱是ucosii中另一种通信机制,可以使一个任务或者中断服务子程序向另一个任务发送一个
指针型的变量(数据缓冲区的指针),为适应不同数据的需要建立了一个数据缓冲区,数据缓冲区
的指针赋给ECB的成员OSEventPrt.
注意区别:消息指针与消息邮箱指针
消息指针为数据缓冲区的指针;消息邮箱的指针为指向ECB的指针。
消息队列
使用消息队列可以在任务间传递多条消息,消息队列相当于一个共用一个等待列表的消息邮箱数
组。
ECB成员OSEventptr指向一个队列控制块的结构,该结构管理一个数组MsgTbl[],该数组元素都是
指向消息的指针。
消息队列的核心是消息指针数组,
向指针数组中插入消息指针的方式有两种:先进先出(FIFO)方式和后进先出(LIFO)方式。
当采用先进先出时,消息队列将在指针OSQIn指向的位置插入消息指针,而把OSQOut指向的消息
指针作为输出;当采用后进先出时,只使用指针OSQOut,当下消息队列插入消息指针时,指
OSQOut 先移动,再按指针OSQOut指向的位置插入消息指针,输出时指针OSQOut无需移动,直
接把OSQOut指向的消息指针作为输出。 |