任务间的同步、事件、事件控制块操作、事件控制块的函数、空事件控制块链表
4.1任务间的同步和事件控制块
4.1.1任务间的同步
任务之间必须建立制约关系:直接制约关系,间接制约关系。
直接制约:源于任务之间的合作,两个任务的执行必须有先后顺序;
间接制约:间接制约关系源于对资源的共享,同一时刻只能有一个任务获取资源。
4.1.2事件
1.信号量
信号量是一类事件,使用信号量的最初目的是为共享资源设立一个表示该共享资源被占用的标志。
2.消息邮箱
(1)多任务操作系统中,常常需要在任务与任务之间传递一个数据(消息)的方式来进行通信;
(2)在内存中创建一个存储空间作为该数据的缓冲区,如果这个缓冲区叫做“消息缓冲区”,任务间传递消息最简单的方法就是传递消息缓冲区的指针。
(3)传递消息缓冲区指针的数据结构就叫做消息邮箱。
3.消息队列
定义一个指针数组,让数组的每个元素都存放一个消息缓冲区指针,任务可以通过传递这个指针数组指针的方法来传递多个消息,这个操作叫做请求消息队列。
4.等待任务列表
对等待任务的管理:对等待事件的所有任务进行记录并排序,允许任务有一定的等待时限。
4.1.3事件控制块
(1)事件控制块ECB,用该数据结构描述信号量、邮箱(消息邮箱)和消息队列这些时间,其中包含任务表在内的所有有关事件的数据。
(2)事件控制块结构如下:
typedef struct
{
INT8U OSEventType; //事件的类型
INT16U OSEventCnT; //信号量计数器
void *OSEventPtr; //消息或消息队列的指针
INT8U OSEventGrp; //等待事件的任务组
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; //任务等待表
}OS_EVENT;
(3)
4.1.4操作事件控制块的函数
1.事件控制块的初始化函数
EventWaitListInit()
原型:
void OS_ EventWaitListInit(
OS_Event *pevent; //事件控制块的指针
);
初始化事件控制块的函数OS_EventWaitListInit(),将在任务调用函数OSXXXCreate()创建事件时,被函数OSXXXCreate()所调用。
2.使一个任务进入等待状态的函数
void OS_EventTaskWait()
{
OS_EVENT *pevent //事件控制块的指针
};
3.使一个正在等待的任务进入就绪状态的函数
INT8U OS_EventTaskRdy(
OS_EVENT *pevent; //事件控制块的指针
void *msg; //未使用
INT8U msk; //清除TCB状态标志掩码
);
函数OS_EventTaskRdy()将在任务调用函数OSXXXPost()发送一个事件时,被函数OSXXXPost所调用。
4.使一个等待超时的任务进入就绪状态的函数
OS_Event(
OS_Event *pevent;
);
4.1.5空事件控制块链表
(1)OS_MAX_EVENTS:在文件OS_CFG.H中定义;表示应用事件的总数;
(2)初始化函数OSInit()创建OS_MAX_EVENTS个空事件控制块并借用成员OSEventPtr作为链接指针,把这些空控制块链接成单向链表。