對消息隊列的學習理解有點難,對技術來說,一本好的書一般是原理和例子相結合的,可惜我找到的很少。書上說消息隊列實際上是多個郵箱組成的數組,是一個列表。這個數組其實是個指針數組,裏面每個指針可以指向不同類型的變量,通過傳遞一個個指針,我們可以做到傳遞指針所指向的一個個變量。(順便複習下,一個郵箱只能傳遞一個指針,而隊列可傳遞多個)。
#include <INCLUDES.H>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
OS_STK TaskStk[3][MaxStkSize];//定義3個堆棧
void task0(void *dat);//定義任務0
void task1(void *dat);//定義任務1
long con1=0;
long con2=0;
OS_EVENT *Com1; //定義一個指針
void *ComMsg1[3]; //定義一個指針數組
u8 err;
u8 st[4]={0x01,0x02,0x03,0x04};//定義一個數組
u8 aa[4]={0x05,0x04,0x06,0x09};//定義一個數組
u8 a1=0xFF;//定義一個數
main()
{
OSInit();//初始化ucosii
InitTimer0();
Com1=OSQCreate(&ComMsg1[0],3);//建立一個消息隊列(即爲數組指針) 消息內存大小爲3
OSQPost(Com1,(void*)&st[0]); //發送到隊列
OSQPost(Com1,(void*)&aa[0]); //發送到隊列
OSQPost(Com1,(void*)&a1); //發送到隊列
OSTaskCreate(task0,(void*)0,&TaskStk[0][0],5);//建立任務 定義好它的優先級等參數
OSTaskCreate(task1,(void*)0,&TaskStk[1][0],6);
OSStart();//系統啓動
}
void task0(void *dat)//任務0
{
dat="dat";//防止編譯有錯誤
while(1)
{
con1++;
OSTimeDly(2);
}
}
void task1(void *dat)
{
u8 *msg1;
u8 cc,b;
dat="dat";//防止編譯有錯誤
while(1)
{
msg1=OSQPend(Com1,0,&err);
cc=*msg1;
b=*(msg1+1);
con2++;
OSTimeDly(2);
}
}
心得:
Com1=OSQCreate(&ComMsg1[0],3),建立一個隊列,將*Com1指針將指向隊列指針數組*ComMsg1[3]的首地址。3表示內存大小。
OSQPost(Com1,(void*)&st[0]),是以先入先出發送消息到隊列,由*ComMsg1[0]指向數組st的首地址,同時隊列消息數加一。
OSQPost(Com1,(void*)&aa[0])發一個消息給隊列,此時是由*ComMsg1[1]指向aa數組的首地址,同時隊列消息數加一。; 依此類推,發下一個也是一樣。(如果隊列滿了,再發送消息到隊列的話,隊列將會出現錯誤)。
msg1=OSQPend(Com1,0,&err);是等待消息隊列函數,獲得指針數組裏的第一個指針ComMsg1[0],該指針指向st[0],。cc=*msg1是通過指針獲得指向的具體值st[0]=0x01;如果再調用一次msg1=OSQPend(Com1,0,&err),將獲得指針數組裏下一個指針ComMsg1[1],依此類推。
每調用一次OSQPend函數,該函數會將隊列的消息減一,Com1指向下一個消息指針*ComMsg1[i++],直到隊列完全沒有消息爲止。在例子中,只有3個消息,程序將執行3次任務1後,隊列已經沒有消息了,所以將任務1暫停。