读书人

uC/OS 的讯息邮箱uC/OS学习笔记(

发布时间: 2013-10-25 14:36:53 作者: rapoo

uC/OS 的消息邮箱——uC/OS学习笔记(五)

1.简介

在多任务操作系统中,常常需要在任务与任务之间通过传递一个数据(也叫做“消息”)的方式进行通信。为了实现这个目的,可以在内存中创建一个存储空间作为该数据的缓冲区。

如果把这个缓冲区叫做消息缓冲区,那么在任务间传递数据的一个简单方法就是传递消息缓冲区的指针。因此,用来传递消息缓冲区指针的数据结构叫做消息邮箱。


2.消息邮箱的操作

a)声明消息邮箱

OS_EVENT *box;

跟信号量一样,声明一个消息邮箱也是OS_EVENT 类型

b)创建消息邮箱

调用函数:OSMboxCreate()

c)向消息邮箱发送消息

调用函数:OSMboxPost()

d)请求消息邮箱

阻塞方式:调用函数:OSMboxPend()

非阻塞方式:调用函数:OSMboxAccept()

e)查询邮箱的状态

调用函数:OSMboxQuery()

f)删除邮箱

调用函数:OSMboxDel()


3.51单片机上测试例程

芯片:STC90C516

开发板:广工无线电开发板

实验程序:矩阵键盘输入-数码管显示。

程序原理:矩阵键盘扫描独立成一个任务。数码管显示独立成一个任务。矩阵键盘得到按键输入后,通过消息邮箱发送给数码管任务。

有些51单片机的内核为了减少空间而裁剪了消息邮箱,所以在使用之前需要配置消息邮箱的代码

完整程序下载地址:http://download.csdn.net/detail/jk050802/6450365

配置os_cfg.h文件:

/* 本例程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();}



读书人网 >操作系统

热点推荐