uC/OS-II學習筆記 訊息佇列
對訊息佇列的學習理解有點難,對技術來說,一本好的書一般是原理和例子相結合的,可惜我找到的很少。書上說訊息佇列實際上是多個郵箱組成的陣列,是一個列表。這個陣列其實是個指標陣列,裡面每個指標可以指向不同型別的變數,通過傳遞一個個指標,我們可以做到傳遞指標所指向的一個個變數。(順便複習下,一個郵箱只能傳遞一個指標,而佇列可傳遞多個)。
#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暫停。