1. 结构
typedef struct os_q { /* QUEUE CONTROL BLOCK */
struct os_q *OSQPtr; /* Link to next queue controlblock in list of free blocks */
void **OSQStart; /* Pointer to start of queuedata */
void **OSQEnd; /* Pointer to end of queue data */
void **OSQIn; /* Pointer to where next messagewill be inserted in the Q */
void **OSQOut; /* Pointer to where next messagewill be extracted from the Q */
INT16U OSQSize; /* Size of queue (maximum numberof entries) */
INT16U OSQEntries; /* Currentnumber of entries in the queue */
} OS_Q;
.OSQPtr 用于构建单链表OSQFreeList, 一旦建立了消息队列,该域就不再有用。
.OSQStart 队列的起点
.OSQEnd 队列的终点
.OSQIn 队列入口指针
.OSQOut 队列出口指针
.OSQSize 队列大小
.OSQEntries 队列已有消息数
2. 消息队列初始化
void OS_QInit (void) reentrant
{
// 队列成员只有一个的情况,建立空队列单链表
#if OS_MAX_QS == 1
OSQFreeList =&OSQTbl[0]; /* Only ONEqueue! */
OSQFreeList->OSQPtr = (OS_Q *)0;
#endif
// 队列成员不止一个的情况,建立空队列单链表
#if OS_MAX_QS >= 2
INT16U i;
OS_Q *pq1;
OS_Q *pq2;
pq1 = &OSQTbl[0];
pq2 = &OSQTbl[1];
for (i = 0; i < (OS_MAX_QS - 1); i++) { /* Init. list of free QUEUE controlblocks */
pq1->OSQPtr = pq2;
pq1++;
pq2++;
}
pq1->OSQPtr = (OS_Q *)0;
OSQFreeList = &OSQTbl[0]; //OSQFreeList 指向链表的首地址
#endif
}
3. 建立一个消息队列
OS_EVENT *OSQCreate (void **start, INT16U size) reentrant
{
...
...
OS_ENTER_CRITICAL();
//从事件控制块空链表里取出一个
pevent = OSEventFreeList;
if (OSEventFreeList != (OS_EVENT *)0) {
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
}
OS_EXIT_CRITICAL();
if (pevent != (OS_EVENT *)0) {
OS_ENTER_CRITICAL();
//从队列空链表里取出一个
pq = OSQFreeList;
if (OSQFreeList != (OS_Q *)0) {
OSQFreeList = OSQFreeList->OSQPtr;
}
OS_EXIT_CRITICAL();
if (pq != (OS_Q *)0) {
// 给新的消息队列元素初始化
pq->OSQStart =start;
pq->OSQEnd =&start[size];
pq->OSQIn = start;
pq->OSQOut = start;
pq->OSQSize = size;
pq->OSQEntries = 0;
pevent->OSEventType = OS_EVENT_TYPE_Q;
pevent->OSEventPtr = pq; //
OS_EventWaitListInit(pevent);
}
//如果没有可用的消息队列空链表,事件控制块放回空链表
else {
OS_ENTER_CRITICAL();
pevent->OSEventPtr = (void *)OSEventFreeList;
OSEventFreeList = pevent;
OS_EXIT_CRITICAL();
pevent = (OS_EVENT *)0;
}
}
return(pevent);
}
示例:
#define MSG_QUEUE_SIZE 2
OS_EVENT *MsgQueue;
void *MsgQueueTbl[MSG_QUEUE_SIZE]; //指针数组
MsgQueue =OSQCreate(&MsgQueueTbl[0], MSG_QUEUE_SIZE);
文章评论(0条评论)
登录后参与讨论