上一篇說了ucos ii的大緻運作原理,這一篇主要用來說明不同任務之間的資料傳遞的。
有人會說:“不同任務間的資料傳遞直接用全局變量不就好了”,我一開始也有這種疑惑,也在簡單程式中實驗過沒什麼問題,但網上一堆大佬說不同任務都調用一個變量,會亂,特别是在大型程式的時候,小程式時間充裕,不會出什麼亂子,也有人說用volatile就可以,暫時沒什麼大型程式可以試驗,就不下總結了。
ucos ii不同任務之間傳遞一個資料或标志時用的是郵箱和信号量,郵箱是用來在不同任務之間傳遞資料(這種資料叫“消息”),資訊量的作用跟标志位一樣,隻是表達的方式不太一樣。信号量分為二值信号量(互斥信号量)和N值信号量(普通信号量),這裡介紹的是N值信号量。
接下來直接上函數:
1.建立郵箱函數 OSMboxCreate(void *msg); 原型為OS_EVENT * OSMboxCreate(void * msg);
函數中的參數msg是消息的指針,函數傳回值是消息郵箱的指針。msg一般初始值為NULL。使用這個函數的時候也可以先建立一個郵箱,然後把這個郵箱的指針作為參數傳遞到函數OSMboxCreate中,比如:
OS_EVENT * msg_key; //消息郵箱
.......
msg_key = OSMboxCreate((void *)0);
.......
2.向郵箱發送消息函數INT8U OSMbosPost(OS_EVENT * pevent,void *msg);
第一個參數pevent是消息郵箱的指針,第二個參數msg是消息指針,函數的功能是把一個變量存入郵箱裡,比如一個掃描按鍵的任務,要把按鍵的值送給别的任務:
void key_task(void *pdata)
{
u8 key;
while(1)
{
key = KEY_Scan(0);
if(key)
OSMboxPost(msg_key,(void *)key); //key的值發送到消息郵箱裡
delay_ms(10);
}
}
3.請求郵箱函數void *OSMboxPend(OS_EVENT *pevent,INT16U timeout,INT8U *err);
三個參數中,pevent是請求郵箱指針,timeout是等待時限,err為錯誤資訊。對應上一個函數,這個函數的功能是把郵箱裡的東西取出來,例如有一個任務是按照按鍵的值執行相應的處理:
void main_task(void *pdata)
{
u32 key;
u8 err;
while(1)
{
key = (u32)OSMboxPend(msg_key,10,&err);
switch(key)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:
break;
}
delay_ms(10);
}
}
第二個參數10是等待時間,時間長短應該跟ucos ii的節拍有關,沒仔細了解過。
4.查詢郵箱狀态函數INT8U OSMboxQuery(OS_EVENT *pevent, OS_MBOX_DATA *pdata);
第一個參數pevent同樣為消息郵箱指針,第二個參數pdata為存放郵箱資訊的結構。
5.删除郵箱函數OS_EVENT *OSMboxDel(OS_EVENT *pevent, INT8U opt, INT8U *err);
就是當郵箱不用的時候删除用的,pevent的是消息郵箱指針,opt是删除選項,err為錯誤資訊,還沒用到這個函數,沒得例子上。。自行百度,Google。。
關于ucos ii的郵箱和信号量現在懂的基本就到這了,更詳細的可以參考《嵌入式實時作業系統μC/OS-II原理及應用》第五章。