1. 程式人生 > >UC/OS-II學習筆記之訊息佇列使用

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暫停