1. 程式人生 > >uCOS II 訊息佇列的使用方法

uCOS II 訊息佇列的使用方法

1、 需在以下檔案中配置如下內容

        OS_CFG.H

        OS_MAX_QS      N     你需要的值

        根據需要自己配置

#define OS_Q_EN                   1    /* Enable (1) or Disable (0) code generation for QUEUES         */

#define OS_Q_ACCEPT_EN            1    /*     Include code for OSQAccept()                             */

#define OS_Q_DEL_EN               1    /*     Include code for OSQDel()                                */

#define OS_Q_FLUSH_EN             1    /*     Include code for OSQFlush()                              */

#define OS_Q_POST_EN              1    /*     Include code for OSQPost()                               */

#define OS_Q_POST_FRONT_EN        1    /*     Include code for OSQPostFront()                          */

#define OS_Q_POST_OPT_EN          1    /*     Include code for OSQPostOpt()                            */

#define OS_Q_QUERY_EN             1    /*     Include code for OSQQuery()                              */

    2、 建立一個指向訊息陣列的指標和陣列的大小,該指標陣列必須申明為void型別,如下:

        void    *MyArrayOfMsg[SIZE];

    3、 宣告一個OS_EVENT型別的指標指向生成的佇列,如下:

        OS_EVENT *QSem;

    4、 呼叫OSQcreate()函式建立訊息佇列,如下:

QSem      = OSQcreate(&MyArrayOfMsg[0],SIZE);

    5、 等待訊息佇列中的訊息,OSQPend()。void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err):

必須保證訊息佇列已經被建立。

timeout定義的是等待超時時間,如果為0則表示無期限的等待

err表示的是在等待訊息隊列出錯時的返回型別,有以下幾種:

OS_ERR_PEVENT_NULL    //訊息佇列不存在

OS_ERR_EVENT_TYPE

OS_TIMEOUT   //訊息佇列等待超時

        OS_NO_ERR             //訊息佇列接收到訊息

獲得訊息佇列示例

type   *GETQ;

INT8U   err;

GETQ   = (type *)OSQPend(QSem, time, &err);

if(err == OS_NO_ERR){

   無錯處理

}

else{

   出錯處理

}

    6.1 向訊息佇列傳送一則訊息(FIFO),OSQPost(); INT8U OSQPost (OS_EVENT *pevent, void *msg):

函式返回值有:

OS_ERR_PEVENT_NULL

OS_ERR_POST_NULL_PTR

OS_ERR_EVENT_TYPE

OS_Q_FULL

OS_NO_ERR

引數:pevent,*msg

    6.2 向訊息佇列傳送一則訊息(LIFO) INT8U OSQPostFront (OS_EVENT *pevent, void *msg)

    6.3 向訊息佇列傳送一則訊息(LIFO或者FIFO) INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)

引數: opt

   如果經opt引數中的OS_POST_OPT_BROADCAST位置為1,則所有正在等待訊息的任務都能接收到這則訊息,並且被OS_EventTaskRdy()從等待列表中刪除

   如果不是廣播方式,則只有等待訊息的任務中優先順序最高的任務能夠進入就緒態。然後,OS_EventTaskRdy()從等待列表中把等待訊息的任務中優先順序最高的任務刪除。

注: 如果此函式由ISR呼叫,則不會發生任務切換,直到中斷巢狀的最外層中斷服務子程式呼叫OSIntExit()函式時,才能進行任務切換

    7、 無等待的從訊息佇列中獲得訊息,OSQAccept(); void *OSQAccept (OS_EVENT *pevent, INT8U *err)

err可能的返回值:

OS_ERR_PEVENT_NULL

OS_Q_EMPTY

OS_NO_ERR

函式的返回值:訊息,0

    8、 清空訊息佇列 INT8U OSQFlush (OS_EVENT *pevent)

函式返回值:

OS_ERR_PEVENT_NULL

OS_ERR_EVENT_TYPE

OS_NO_ERR

    9、 獲取訊息佇列的狀態,OSQQuery(); INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *p_q_data)

函式返回值:

OS_ERR_PEVENT_NULL

OS_ERR_EVENT_TYPE

OS_NO_ERR

OS_Q_DATA資料結構在ucos_ii.h中

// 採用訊息佇列的ADC取樣任務原型程式碼,建議與uC/OS-II作者的ADC通用例程一起使用

// 說明這裡訊息佇列msg_q不用於儲存ADC結果。

void ADCTask(void * pParam)

{

char *cmd;

pParam=pParam;

while(1)

{

cmd=OSQPend(msg_q,100,&err); // waiting for command

if(err==OS_NO_ERR)

{

switch (*cmd)

{

case '1': printf("Command 1\n"); break;

case '2': printf("Command 2\n"); break;

default : printf("Error command.\n"); break;

}

}

else

{// no command , then sampling...

if(err==OS_TIMEOUT) // sampling while timeout.

printf("ADC sampling ...");

StoreADResult();

}

}

}

補充:訊息佇列用於緩衝事件。事件不知道什麼時候會到來,也不能保證來了就能迅速得到處理。    使用訊息佇列,可以保證每個事件都被處理到,以及處理順序。

還有兩種情況下會用到訊息佇列:

         儲存外部事件:外部事件由中斷收集,然後儲存到佇列。

        串列埠接收程式中的接收迴圈緩衝區,可理解為訊息佇列。

IRQ英文全稱Interrupt Request,中文翻譯為中斷請求線。計算機中有許多裝置(例如音效卡、硬碟等)他們都能在沒有CPU介入的情況下完成一定的工作。但是這些裝置還是需要定期中斷CPU,讓CPU為其做一些特定的工作。如果這些裝置要中斷CPU的執行,就必需在中斷請求線上把CPU中斷的訊號發給CPU。所以每個裝置只能使用自己獨立的中斷請求線。一般來說在80286以上計算機中,共有16箇中斷請求線與各種需要用中斷的不同外設相連線,(每個中斷線有一個標號也就是中斷號)。

  中斷號的分配情況如下:

  IRQ 說明

  0 定時器

  1 鍵盤

  2 序列裝置控制器

  3 COM2

  4 COM1

  5 LPT2

  6 軟盤控制器

  7 LPT1

  8 實時時鐘

  9 PC網路

  10 可用(Available)

  11 可用(Available)

  12 PS/2 滑鼠

  13 數學協處理器

  14 硬碟控制器

  15 可用(Available)

  NM1 奇偶校驗

  大家現在就可以清楚的看到,IRQ3、4、5、10、11、12、15可供用使用。