ucos消息队列与消息邮箱不同的是:
消息队列事件结构体成员 &message 不只是指向一个消息的地址 而是指向一个(结构体)消息队列控制块OS_Q
而在OS_Q的成员中OSQStart 成员指向了一个一个指针数组 *messagegroup[size] 这个是自己认为定义的 size的大小决定能存放的消息最大数量
在创建消息队列是把*messagegroup c传递给创建函数
*messagegroup 中每个成员是存放的是每个要发送的消息的地址
然后OS_Q 中的其他成员用于指向队列头尾什么的 实现一个队列机制
函数实现主要部分如下
OS_EVENT *OSQCreate (void **start, INT16U size) //**start用于接收存放消息地址的指针数组
pq->OSQStart = start; /* Initialize the queue */
pq->OSQEnd = &start[size]; //指向数组末尾的下一个地址,start[size-1]为最后一个数据
pq->OSQIn = start; //刚开始 头尾指针都指向数组头部
pq->OSQOut = start;
pq->OSQSize = size;
pq->OSQEntries = 0u; //记录消息数量
pevent->OSEventType = OS_EVENT_TYPE_Q;
pevent->OSEventCnt = 0u;
pevent->OSEventPtr = pq;
void *OSQPend (OS_EVENT *pevent, //消息队列事件
INT32U timeout, //等待时间
INT8U *perr)
//以下是队列实现机制
if (pq->OSQEntries > 0u) { /* 判断队列是否为空 */
pmsg = *pq->OSQOut++; /* 消息出队列 头部(out)地址加1 */
pq->OSQEntries--; /* 消息数量-1 */
if (pq->OSQOut == pq->OSQEnd) { /* 如果头部加到数组尾部了 又重新开始*/
pq->OSQOut = pq->OSQStart;
}
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (pmsg); /* Return message received */
}
INT8U OSQPost (OS_EVENT *pevent,
void *pmsg)
if (pq->OSQEntries >= pq->OSQSize) { /* 确保 不是满的 */
OS_EXIT_CRITICAL();
return (OS_ERR_Q_FULL);
}
*pq->OSQIn++ = pmsg; /* 插入消息 in+1 */
pq->OSQEntries++; /* Update the nbr of entries in the queue */
if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
pq->OSQIn = pq->OSQStart;
}
OS_EXIT_CRITICAL();