上一篇说了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原理及应用》第五章。