原创 UCOS-II中消息队列学习笔记(1)

2011-12-7 22:36 3246 19 19 分类: MCU/ 嵌入式

 

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);

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
19
关闭 站长推荐上一条 /1 下一条