有关UCOS任务的介绍:
STM32上使用UCOSII–任务
有关UCOS信号量和邮箱的介绍:
STM32上使用UCOSII–信号量和邮箱
一、 消息队列
使用消息队列可以在任务之间传递多条消息。消息队列由三个部分组成:事件控制块、消息队列和消息。当把事件控制块成员 OSEventType 的值置为 OS_EVENT_TYPE_Q 时,该事件控制块描述的就是一个消息队列。
消息队列的数据结构如图:
消息队列相当于一个共用一个任务等待列表的消息邮箱数组,事件控制块成员OSEventPtr指向了一个叫做队列控制块(OS_Q)的结构,该结构管理了一个数组 MsgTbl[],该数组中的元素都是一些指向消息的指针
队列控制块( OS_Q)的结构定义如下:
typedef struct os_q
{
struct os_q *OSQPtr;
void **OSQStart;
void **OSQEnd;
void **OSQIn;
void **OSQOut;
INT16U OSQSize;
INT16U OSQEntries;
} OS_Q;
参数 | 说明 |
---|---|
OSQPtr | 指向下一个空的队列控制块 |
OSQSize | 数组的长度 |
OSQEntres | 已存放消息指针的元素数目 |
OSQStart | 指向消息指针数组的起始地址 |
OSQEnd | 指向消息指针数组结束单元的下一个单元。它使得数组构成了一个循环的缓冲区 |
OSQIn | 指向插入一条消息的位置。当它移动到与 OSQEnd 相等时,被调整到指向数组的起始单元 |
OSQOut | 指向被取出消息的位置。当它移动到与 OSQEnd 相等时,被调整到指向数组的起始单元 |
其中,可以移动的指针为 OSQIn 和 OSQOut,而指针 OSQStart 和 OSQEnd 只是一个标志(常指针)。当可移动的指针 OSQIn 或 OSQOut 移动到数组末尾,也就是与OSQEnd相等时,可移动的指针将会被调整到数组的起始位置OSQStart。也就是说,从效果上来看,指针 OSQEnd与 OSQStart 等值。于是,这个由消息指针构成的数组就头尾衔接起来形成了一个循环的队列
消息队列相关函数
1. 创建消息队列函数
OS_EVENT *OSQCreate(void**start,INT16U size);
start 为存放消息缓冲区指针数组的地址
size 为该数组大小
2. 请求消息队列函数
void*OSQPend(OS_EVENT*pevent,INT16U timeout,INT8U *err);
pevent 为所请求的消息队列的指针
timeout 为任务等待时限
err 为错误信息
3. 向消息队列发送消息函数
INT8U OSQPost(OS_EVENT *pevent,void *msg);//先进先出
INT8U OSQPostFront(OS_EVENT *pevent,void*msg); //后进先出
pevent 为消息队列的指针
msg 为待发消息的指针
二、 信号量集
UCOSII 为了实现多个信号量组合的功能定义了一种特殊的数据结构——信号量集
不同于信号