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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章