- 消息队列的操作
- 创建消息队列
创建一个消息队列首先需要定义一个指针数组,然后把各个消息数据缓冲区的首地址存入这个数组,最后在调用函数OSQCreate()来创建消息队列。创建消息队列函数OSQCreate()的原型如下:
OS_EVENT *OSQCreate(
void **start, //指针数组的地址
INT16U size //数组长度
)
函数中的参数start为存放在消息缓冲区指针数组的地址;参数size为该数组的大小。函数的返回值为消息队列的指针。
函数OSQCreate()首先从空闲队列控制块链表摘取一个控制块并按参数start和size填写诸项,然后把消息队列初始化为空(即其中不包含任何消息)。
- 请求消息队列
请求消息队列的目的是从消息队列中获取消息。任务请求消息队列需要调用函数OSQPend()。该函数的原型如下:
void *OSQPend(
OS_EVENT *pevent,
INT16U timeout, //等待时限
INT8U *err
)
函数的返回值为消息指针。
函数的参数pevent是要访问的消息队列事件控制块的指针;参数timeout是任务等待时限。
函数需要通过访问事件控制块的成员OSEventPtr指向的队列控制块OS_Q的成员OSQEntries来判断是否有消息可用。如果有消息可用,则返回OS_Q成员OSQOut指向的消息,同时调整指针OSQOut,使之指向下一条消息并把有效消息数的变量OSQEntries减1;如果无消息可用(即OSQEntries=0),则使用函数OSQPend()的任务挂起,使之处于等待状态并引发一次任务调度。
如果希望任务无任务等待地请求一个消息队列,则可调用函数OSQAccept()。该函数的原型如下:
void OSQAccept(
OS_EVENT *pevent
)
- 向消息队列发送消息
任务需要通过调用函数OSQPost()或OSQPostFront()来向消息队列发送消息。
其中,函数OSQPend()以FIFO(先进先出)的方式组织消息队列;函数OSQPostFront()
以LIFO(后进先出)的方式组织消息队列。这两个函数的原型如下:
INT8U OSQPost(
OS_EVENT *pevent,
void *msg
)
和
INT8U OSQPostFront(
OS_EVENT *pevent,
void *msg
)
函数中的参数msg为待发消息的指针。
如果任务希望以广播的方式通过消息队列发送消息,则需要调用函数OSQPostOpt()。该函数的原型如下:
INT8U OSQPostOpt(
OS_EVENT *pevent,
void *msg,
INT8U opt
)
调用这个函数发送消息时,如果参数opt的值为OS_POST_OPT_DROADCASE,则凡是等待该消息队列的所有任务都会收到消息。
- 清空消息队列
任务可以通过调用函数OSQFlush()来清空消息队列。该函数的原型如下:
INT8U OSQFlush(
OS_EVENT *pevent
)
- 删除消息队列
任务可以通过调用函数OSQDel()来删除已存在的消息队列。该函数的原型如下:
OS_EVENT *OSQDel(
OS_EVENT *pevent
)
- 查询消息队列
任务可以通过调用函数OSQQuery()来查询一个消息队列的状态。该函数的原型如下:
INT8U OSQQuery(
OS_EVENT *pevent,
OS_Q_DATA *pdata //存放消息队列信息的结构
)
函数中的参数pdata是OS_Q_DATA *pdata类型的指针。OS_Q_DATA *pdata的结构如下:
typedef struct{
void *OSMsg;
INT16U OSNMsg;
INT16U OSQSize;
INT8U OSEventTbl[OS_EVENT_TBL_SIZE];
INT8U OSEventGrp;
}OS_Q_DATA;