uC/OS 的訊息郵箱——uC/OS學習筆記(五)
阿新 • • 發佈:2019-02-13
1.簡介
在多工作業系統中,常常需要在任務與任務之間通過傳遞一個數據(也叫做“訊息”)的方式進行通訊。為了實現這個目的,可以在記憶體中建立一個儲存空間作為該資料的緩衝區。
如果把這個緩衝區叫做訊息緩衝區,那麼在任務間傳遞資料的一個簡單方法就是傳遞訊息緩衝區的指標。因此,用來傳遞訊息緩衝區指標的資料結構叫做訊息郵箱。
2.訊息郵箱的操作
a)宣告訊息郵箱
OS_EVENT *box;
跟訊號量一樣,宣告一個訊息郵箱也是OS_EVENT 型別
b)建立訊息郵箱
呼叫函式:OSMboxCreate()
c)向訊息郵箱傳送訊息
呼叫函式:OSMboxPost()
d)請求訊息郵箱
阻塞方式:呼叫函式:OSMboxPend()
非阻塞方式:呼叫函式:OSMboxAccept()
e)查詢郵箱的狀態
呼叫函式:OSMboxQuery()
f)刪除郵箱
呼叫函式:OSMboxDel()
3.51微控制器上測試例程
晶片:STC90C516
開發板:廣工無線電開發板
實驗程式:矩陣鍵盤輸入-數碼管顯示。
程式原理:矩陣鍵盤掃描獨立成一個任務。數碼管顯示獨立成一個任務。矩陣鍵盤得到按鍵輸入後,通過訊息郵箱傳送給數碼管任務。
有些51微控制器的核心為了減少空間而裁剪了訊息郵箱,所以在使用之前需要配置訊息郵箱的程式碼
配置os_cfg.h檔案:
#define OS_MBOX_EN 1 /* Enable (1) or Disable (0) code generation for MAILBOXES */ #define OS_MBOX_ACCEPT_EN 1 /* Include code for OSMboxAccept() */ #define OS_MBOX_DEL_EN 0 /* Include code for OSMboxDel() */ #define OS_MBOX_POST_EN 1 /* Include code for OSMboxPost() */ #define OS_MBOX_POST_OPT_EN 0 /* Include code for OSMboxPostOpt() */ #define OS_MBOX_QUERY_EN 0 /* Include code for OSMboxQuery() */
下面是main.c檔案
/* 本例程uCOS-II 版本為2.51*/
#include "includes.h"
#define uchar unsigned char
#define uint unsigned int
/* 共陰數碼管編碼 */
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
#define DATA_OUT P2 //巨集定義 數碼管段選
#define BIT_CHOOSE P0 //巨集定義 數碼管位選
uchar num,temp;
uchar key_number;
OS_STK Task1Stk[MaxStkSize+1];
OS_STK Task2Stk[MaxStkSize+1];
OS_EVENT* my_box; //定義訊息郵箱
INT8U err;
uchar key_scan() //鍵盤掃描
{
P1=0xfe; //掃描第一行
temp=P1;
temp&=0xf0;
if(temp!=0xf0) //檢測有按鍵按下
{
OSTimeDlyHMSM(0,0,0,5);
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp) //判斷按下是哪一個按鍵
{
case 0xee:num=0;
break;
case 0xde:num=1;
break;
case 0xbe:num=2;
break;
case 0x7e:num=3;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp&=0xf0;
}
}
}
P1=0xfd; //掃描第二行
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
OSTimeDlyHMSM(0,0,0,5);
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=4;
break;
case 0xdd:num=5;
break;
case 0xbd:num=6;
break;
case 0x7d:num=7;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp&=0xf0;
}
}
}
P1=0xfb; //掃描第三行
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
OSTimeDlyHMSM(0,0,0,5);
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=8;
break;
case 0xdb:num=9;
break;
case 0xbb:num=10;
break;
case 0x7b:num=11;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp&=0xf0;
}
}
}
P1=0xf7; //掃描第四行
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
OSTimeDlyHMSM(0,0,0,5);
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=12;
break;
case 0xd7:num=13;
break;
case 0xb7:num=14;
break;
case 0x77:num=15;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp&=0xf0;
}
}
}
return num; //返回按鍵對應編號
}
/* 數碼管任務 */
void Task1(void *ppdata) reentrant
{
uchar i=0;
uchar *number;
ppdata=ppdata;
DATA_OUT=0X00;
BIT_CHOOSE=0XFF;
for(;;)
{
number = OSMboxPend(my_box,10,&err); //阻塞式請求訊號量
//number = OSMboxAccept(my_box); //非阻塞式請求訊號量,測試不成功
DATA_OUT=tab[*number];
BIT_CHOOSE = ~1;
OSTimeDlyHMSM(0,0,0,2);
}
}
void Task2(void *ppdata) reentrant
{
ppdata=ppdata;
for(;;)
{
key_number = key_scan();
OSMboxPost(my_box,&key_number); //傳送訊號量
OSTimeDlyHMSM(0,0,0,10);
}
}
void main(void)
{
OSInit();
InitHardware();
my_box=OSMboxCreate((void* )0);//定義一個訊號量
OSTaskCreate(Task1,(void*)0,&Task1Stk[0],0);
OSTaskCreate(Task2,(void*)0,&Task2Stk[0],1);
OSStart();
}