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可供用使用。