新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32 uCOS_II 實(shí)踐 之 消息郵箱

STM32 uCOS_II 實(shí)踐 之 消息郵箱

作者: 時(shí)間:2016-12-03 來源:網(wǎng)絡(luò) 收藏
所謂的消息郵箱并不是把數(shù)據(jù)進(jìn)行傳輸,而是在合適的時(shí)間告訴任務(wù)去使用哪些變量或者當(dāng)一些特殊的變量變化后可以及時(shí)并準(zhǔn)確的使用變量,消息郵箱傳遞的是這些變量的指針,而這些變量本身就已經(jīng)存在與內(nèi)存中了,他們多以全局變量或者靜態(tài)變量的形式存在。

首先介紹消息郵箱的一種使用方式,就是只傳遞一個(gè)非空指針,告訴等待消息的任務(wù)他等待的時(shí)間到了,但是這個(gè)指針里并沒有有用的數(shù)據(jù),而任務(wù)中也不應(yīng)該對(duì)這個(gè)地址指向的變量進(jìn)行任何的讀取和寫入操作,讀寫操作都是無意義的,從另外一個(gè)角度來看,雖然借用了別人的地址但是本身并沒有對(duì)地址里的數(shù)據(jù)進(jìn)行操作,所以地址里的數(shù)據(jù)也是安全的,說白了就是消息郵箱版信號(hào)量(非計(jì)數(shù))。它的好處就是可以在系統(tǒng)里把信號(hào)量有關(guān)的代碼給裁剪掉,但缺點(diǎn)是他并無法達(dá)到信號(hào)量的全部功能,這種用法無法進(jìn)行計(jì)數(shù),只是單純的傳遞一次狀態(tài)。如果把消息隊(duì)列改造成計(jì)數(shù)信號(hào)量,個(gè)人覺得很沒必要,除非你選的MCU非常的尷尬。權(quán)且就讓這種方式作為初步了解消息郵箱的一個(gè)引子吧。

本文引用地址:http://butianyuan.cn/article/201612/325154.htm

使用消息郵箱可以分為4個(gè)步驟:

步驟1:聲明一個(gè)指針變量,這個(gè)指針變量在初始化消息郵箱的時(shí)候會(huì)把這個(gè)消息郵箱對(duì)應(yīng)的事件控制塊的指針存放進(jìn)去。

void *Mbox_Task_LED1;

步驟2:對(duì)消息郵箱進(jìn)行初始化,也就是初始化對(duì)應(yīng)的事件控制塊,并且會(huì)把這個(gè)事件控制塊的指針作為返回值賦值給第一步聲明的指針變量。消息郵箱初始化函數(shù)有一個(gè)參數(shù),應(yīng)該設(shè)置為空指針,表示消息郵箱為空。

Mbox_Task_LED1 = OSMboxCreate((void *)0);

步驟3:在任務(wù)里設(shè)置等待消息函數(shù),當(dāng)這個(gè)任務(wù)執(zhí)行到這句話的時(shí)候,系統(tǒng)會(huì)把這個(gè)任務(wù)掛起,等待有消息的發(fā)送。這個(gè)函數(shù)里有3個(gè)變量,第一個(gè)參數(shù)是指等待的是哪個(gè)消息郵箱,第二個(gè)參數(shù)是指等待時(shí)間單位為系統(tǒng)心跳,0指無時(shí)間期限的等待,第三個(gè)參數(shù)為返回的錯(cuò)誤類型。

OSMboxPend(Mbox_Task_LED1,0,&err);

步驟4:在其他的任務(wù)里或者中斷服務(wù)程序里設(shè)置發(fā)送消息函數(shù),需要注意的是,這個(gè)函數(shù)并不會(huì)引起系統(tǒng)調(diào)度,所以如果把它放在中斷服務(wù)函數(shù)里的話就要去中斷里的內(nèi)容盡量簡短,以保證消息發(fā)送出去后,能進(jìn)來快的進(jìn)行系統(tǒng)調(diào)度讓消息接受函數(shù)相應(yīng)。在這個(gè)函數(shù)里有2個(gè)參數(shù),第一個(gè)參數(shù)為要發(fā)送給哪個(gè)消息郵箱,第二個(gè)參數(shù)為發(fā)送的數(shù)據(jù)的地址。在這里其實(shí)并沒有真實(shí)的數(shù)據(jù),只是把發(fā)送的地址用了一個(gè)非空地址,這個(gè)地址及其指向的數(shù)據(jù)都沒有任何意義,也不需要進(jìn)行任何的讀寫操作,只是傳遞一個(gè)消息到相應(yīng)的等待函數(shù),以解除對(duì)應(yīng)任務(wù)的掛起狀態(tài)。

OSMboxPost(Mbox_Task_LED1,(void *)1);

下面看下具體的代碼:
步驟2和步驟3:

void Task_LED1(void* p_arg)
{
(void) p_arg ;

Mbox_Task_LED1 = OSMboxCreate((void *)0); // 創(chuàng)建消息郵箱,初值為空指針
while(1)
{
OSMboxPend(Mbox_Task_LED1,0,&err); // 等待郵箱的消息

LED1_HIGH;
OSTimeDlyHMSM(0,0,1,0);
LED1_LOW;
OSTimeDlyHMSM(0,0,1,0); // 延時(shí),用來給其他任務(wù)留有運(yùn)行的時(shí)間
}
}

步驟4:

void Interrupt_Handle_KEY3(void)
{
OSIntEnter();

// 在中斷服務(wù)函數(shù)里如果調(diào)用ucos系統(tǒng)函數(shù)的話就必須加上進(jìn)中斷系統(tǒng)函數(shù)出去的時(shí)候要加上出中斷系統(tǒng)函數(shù)

OSMboxPost(Mbox_Task_LED1,(void *)1);

// 發(fā)送郵箱消息,這個(gè)函數(shù)并不會(huì)引起系統(tǒng)調(diào)度,所以中斷服務(wù)函數(shù)一定要簡潔。
EXTI_ClearITPendingBit(EXTI_Line3); // 清除標(biāo)志位

OSIntExit();
}

=======================================================================================================
下面說下傳遞一個(gè)真實(shí)的變量,步驟和上面是一樣的,只不過在步驟3和步驟4的地方會(huì)有對(duì)變量的轉(zhuǎn)換。代碼如下:
步驟2和步驟3:

void Task_LED1(void* p_arg)
{
unsigned char num ;
unsigned char pp;
(void) p_arg ;

Mbox_Task_LED1 = OSMboxCreate((void *)0); // 創(chuàng)建消息郵箱,初值為空指針
while(1)
{
num = *(unsigned char *)OSMboxPend(Mbox_Task_LED1,0,&err); // 等待郵箱的消息
pp = num; // 這個(gè)變量用于仿真時(shí)數(shù)據(jù)監(jiān)測(cè)
while(pp--)
{
LED1_HIGH;
OSTimeDlyHMSM(0,0,0,200);
LED1_LOW;
OSTimeDlyHMSM(0,0,0,200);
}
}
}

步驟4:

void Interrupt_Handle_KEY3(void)
{
OSIntEnter();

// 在中斷服務(wù)函數(shù)里如果調(diào)用ucos系統(tǒng)函數(shù)的話就必須加上進(jìn)中斷系統(tǒng)函數(shù)出去的時(shí)候要加上出中斷系統(tǒng)函數(shù)

OSMboxPost(Mbox_Task_LED1,(void *)&Num);

// 發(fā)送郵箱消息,這個(gè)函數(shù)并不會(huì)引起系統(tǒng)調(diào)度,所以中斷服務(wù)函數(shù)一定要簡潔。
EXTI_ClearITPendingBit(EXTI_Line3); // 清除標(biāo)志位

OSIntExit();
}

如步驟4紅色注釋部分,在發(fā)送的時(shí)候把一個(gè)具體的變量取地址,并且強(qiáng)制轉(zhuǎn)換為一個(gè)無定義變量的指針;在步驟3紅色注釋部分,在等待函數(shù)外部首先進(jìn)行的時(shí)候變量類型的轉(zhuǎn)換,轉(zhuǎn)換成一個(gè)無符號(hào)字符型變量的指針,然后在進(jìn)行間指操作,把地址里的數(shù)據(jù)取出來,最后賦值給函數(shù)的臨時(shí)變量進(jìn)行使用。				   


關(guān)鍵詞: STM32uCOSII消息郵

評(píng)論


技術(shù)專區(qū)

關(guān)閉