第四章任务的同步与通信
4.1.1 任务间的同步
为了实现各任务之间的合作和无冲突的运行,在各任务之间必须建立一些制约关系。其中一种制约关系叫做直接制约关系,另外一种制约关系叫做间接制约关系。
在多任务合作工作的过程中,操作系统应该解决两个问题:
1、各任务间应该具有一种互斥关系,即对于某个共享资源,如果一个任务正在使用,则其他任务只能等待,等到该任务释放资源后,等待的任务之一才能使用它;(直接制约关系)
2、相关的任务在执行上有先后次序,一个任务要等其伙伴发来通知,或建立了某个条件后才能继续执行,否则只能等待。(间接制约关系)
任务之间这种制约性的合作运行机制叫做任务间的同步。系统中任务的同步是依靠任务与任务之间互相发送消息来保证同步的。
4.1.2 事件
uC/OS-ll把任务发送事件、请求事件以及其他对事件的操作都定义成全局函数,以供应用程序的所有任务来调用。
1、 信号量
信号量是一类事件。我们用信号来作为标志位来表示此共享资源是否被占用的情况
2、 消息邮箱
在多任务操作系统中,我们在内存中创建一个存储空间作为任务与任务间通过传递数据的数据缓冲区使之进行通信。在任务间传递数据的一个最简单的方法就是传递消息缓冲区的指针,我们称传递消息缓冲区指针的数据结构叫做消息邮箱。
3、 消息队列
定义:传递多个消息的数据结构叫做消息队列
如图是两个任务使用消息队列进行通信的示意图。任务1向消息队列发送消息缓冲区指针数组的指针,这个操作叫做发送消息队列;任务2从消息队列读取消息缓冲区指针数组的指针,这个操作叫做请求消息队列。
4、 等待任务列表
uC/OS-ll将信号量、消息邮箱、消息队列这类用于任务同步和通信的数据结构叫做事件。为了完善事件,我们对这些等待任务具有一定管理功能:
1、对等待事件的所有任务进行记录并排序;
2、允许任务有一定的等待时限。
与任务就绪表相似,在等待任务列表中uC/OS-ll使用一个INT8U类型的数组OSEvent1[]作为记录等待任务的记录表。
4.1.3 事件控制块
在uC/OS-ll中,为了将描述事件的数据结构统一起来,使用时间控制块。我们通过指针pevent访问事件控制块。
其中,OSEventTbl[OS_EVENT_TAL_SIZE]是一个数组,跟前面的任务就绪表一样,所以的任务按照优先级别各自在表中占据一个二进制位
4.1.4 操作事件控制块的函数
1.时间控制块初始化函数:将变量OSEventGrp及任务等待表中每一位都清0,即令事件任务等待表中不含有任何等待任务
2.使一个任务进入等待状态的函数:OS_EventTaskWait()
3.使一个正在等待任务进入就绪状态的函数:OS_EventTaskRdy(),作用是将任务等待表中位置清0,再把任务就绪表中对应的位置置1
4.使一个等待超时的任务进入就绪状态的函数:OS_EventTO()
4.1.5 空事件控制块链表
uC/OS-ll系统在初始化时,创建一个按照应用程序总数为标准的空事件控制块,并借用OSEventPtr作为连接指针将控制链接成一个单向链表