永发信息网

ucos菜鸟提问:关于ucos操作系统中如何从邮箱中提取出消息

答案:4  悬赏:0  手机版
解决时间 2021-01-26 02:21
ucos菜鸟提问:关于ucos操作系统中如何从邮箱中提取出消息
最佳答案
首先介绍消息邮箱的一种使用方式:即只传递一个非空指针,告诉等待消息的任务时间到了,但是这个指针里并没有可用的数据,而任务中也不可对这个地址指向的变量进行任何的读取和写入操作,读写操作都是无意义的,从另外一个角度来看,虽然借用了别人的地址但是本身并没有对地址里的数据进行操作,所以地址里的数据也是安全的,也就是消息邮箱版信号量(非计数),下面介绍详细步骤:
  步骤1:声明一个指针变量,这个指针变量在初始化消息邮箱的时候会把这个消息邮箱对应的事件控制块 的指针存放进去。 void *Mbox_Task_LED1;
  步骤2:对消息邮箱进行初始化,也就是初始化对应的事件控制块,并且会把这个事件控制块的指针作为返回值赋值给第一步声明的指针变量。消息邮箱初始化函数有一个参数,应该设置为空指针,表示消息邮箱为空。 Mbox_Task_LED1 = OSMboxCreate((void *)0); 步骤3:在任务里设置等待消息函数,当这个任务执行到这句话的时候,系统会把这个任务挂起,等待有消息的发送。这个函数里有3个变量,第一个参数是指等待的是哪个消息邮箱,第二个参数是指等待时间单位为系统心跳,0指无时间期限的等待,第三个参数为返回的错误类型。OSMboxPend(Mbox_Task_LED1,0,&err);
  步骤4:在其他的任务里或者中断服务程序里设置发送消息函数,需要注意的是,这个函数并不会引起系统调度,所以如果把它放在中断服务函数里的话就要去中断里的内容尽量简短,以保证消息发送出去后,能进来快的进行系统调度让消息接受函数相应。在这个函数里有2个参数,第一个参数为要发送给哪个消息邮箱,第二个参数为发送的数据的地址。在这里其实并没有真实的数据,只是把发送的地址用了一个非空地址,这个地址及其指向的数据都没有任何意义,也不需要进行任何的读写操作,只是传递一个消息到相应的等待函数,以解除对应任 务的挂起状态。
全部回答
给你个例程,是用来控制LED亮灭的UC0S,main()函数,有关键部分的注释:
#include "../SOURCE/includes.h"
#include "../inc/44blib.h"
#include "..\inc\44b.h"
#include "../target/target.h"
#define STACKSIZE 512 //定义堆栈长度

OS_STK StartTaskStk[STACKSIZE]; //声明堆栈分区
OS_STK Led1TaskStk[STACKSIZE];
OS_STK Led2TaskStk[STACKSIZE];
char *s1="\n led1灯亮! ";
char *s2="\n led2灯亮! ";
INT8U err;
OS_EVENT *Str_Box; //定义事件控制块指针 邮箱指针
void StartTask(void *data); //声明任务函数
void Led1Task(void *data);
void Led2Task(void *data);
//****************************** MAIN() ************************************
void Main(int argc, char **argv)
{
TargetInit(); //初始化开发板硬件环境
OSInit(); //初始化OS
Str_Box=OSMboxCreate((void *)0); //创建消息邮箱
OSTaskCreate(StartTask,(void *)0,&StartTaskStk[STACKSIZE-1],0); //创建起始任务
OSStart(); //运行多任务管理OS
}
//***************************** 起始任务函数 ****************************
void StartTask(void *pdata)
{
pdata=pdata; //避免编译器报错
TargetStart(); //配置和打开中断,系统时钟开始运行
OSTaskCreate(Led1Task,(void *)s1,&Led1TaskStk[STACKSIZE-1],3);//创建LED1任务
OSTaskCreate(Led2Task,(void *)s2,&Led2TaskStk[STACKSIZE-1],4);//创建LED2任务
}
void Led1Task(void *pdata)
{
INT8U *ss;
for(;;)
{
ss=(INT8U*)OSMboxPend(Str_Box,0,&err); //向消息邮箱请求消息,返回消息的指针
if(*ss==1) //获取消息指针的值,然后进行判断
{
rPDATC=0x02; //点亮第一个灯
Uart_Printf(pdata); //打印"LED1灯亮"
Uart_Printf(" \n 获得的消息:%d",*ss);
}
OSTimeDlyHMSM(0,0,5,0); //延时5秒
}
}
void Led2Task(void *pdata)
{
INT8U s;
for(;;)
{
Uart_Printf(pdata);
rPDATC=0x04;
s=1;
OSMboxPost(Str_Box,&s); //向邮箱发送消息
Uart_Printf(" \n 发送的消息:%d",s);
OSTimeDlyHMSM(0,0,2,0); //延时2秒
}
}
可以定义一个字符串s=“HOW ARE YOU”,在task1中将其指针用OSMboxPost发出去,task2用OSMboxPend等待这个信息就行了。具体函数的参数你就得参考一些例子啦。推荐北航的那本ucos 原理及应用,任哲写的。具体书名我不是记得很清楚。
首先设task1任务的优先级为10
task2任务的优先级为15
OSMboxCreat(void *msg)函数的参数可以为空即Mbox1=OSMboxCreat((void*)0)
表示在刚建立的消息邮箱为空,也可以不为空即msg为指向消息的指针。
同时再建立另一个邮箱Mbox2=OSMboxCreat((void*)0)
task1(void *pdata)
{
static INT8U RxBuf={how are you};
INT8U err;
INT8U x;
pdata = pdata;
x = 0;
for(;;)
{
OSMboxPost(Mbox1,(void*)&RxBuf[x]);
OSMboxPost(Mbox2,0,&err);
x++;
if (Rxbuf[x] == 'u') x = 0;
}
}

task2(void *pdata)
{
INT8U err;
INT8U *msg;
pdata = pdata;
for(;;)
{
msg = (INT8U*)OSMboxPend(Mbox1,10,&err);
printf("%c",*msg);
OSTimeDlyHMSM(0,0,1,0);
OSMboxPost(Mbox2,(void*)1);

}
}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
开车追尾电动车~对方胳膊擦伤,给对方修电动
【水银弯刀】LOL水银系带(弯刀)移除你英雄身
淄博张店四宝山有什么企业?有多少污染企业!!!
鲁迅童年的生活状况
永益眼镜地址在什么地方,想过去办事
【The library is】
金叶地址在哪,我要去那里办事
化妆品对人体有害吗
河北银行的信用卡上了黑名单,会影响其它行信
老哥们,瞎子现在走全属强还是光属强比较好
我已经在广州千聚做了免费MMPI在线测试,到这
做提肛运动,性能力真能提高么,就是收紧肛门
视康眼镜地址在什么地方,想过去办事
江淮汽车水温表不准怎么办,应该检查哪?
以下有关双膦酸盐应用注意事项的叙述中,正确
推荐资讯
求助 ,, 在58同城找的工作,是物流长途运货
射线A?B大于线段B?C.________.
(m-n) ³×(n-m) ³×(n-m)的4次方
男生对女生身体的哪个部位最好奇?想看看!
今天11月2日星期三,推迟三天是几号星期几
1802—1803年,英格兰和威尔士的济贫税年均为
火山物质沉积岩与火成岩的区别
成语鼎鼎有名的意思是什么啊?有知道释义的请
我的新鱼缸刚加的水,有个500瓦的加热棒,我
院子里能不能放石磨
长城电脑显示屏闪是啥毛病
CSOL盘龙血煞开6是不是无效的?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?