UCOSII信号量 邮箱
UCOSII中,使用信号量、邮箱(消息邮箱)和消息队列来实现任务之间的通信。
信号量:
信号量像一把钥匙,任务要运行下去,需先拿到这把钥匙。
信号量是一个触发信号,也是一个计数器,等待接收信号的任务一般只有接收到信号才可以执行,否则任务一直暂停。
在uCOSII里面,等待信号量的任务可以设置无限等待或等待若干个时钟节拍后,任务自动恢复执行。具体看自己的要求来设置。
1 创建信号量函数
OS_EVENT *OSSemCreate (INT16U cnt);
参数cnt:信号量计数器(OSEventCnt)的初始值。
返回值:已创建的信号量的指针,指针变量类型为OS_EVENT
2 等待一个信号量函数
void OSSemPend ( OS_EVENT *pevent, INT16U timeout, INT8U *err);
pevent :信号量指针
timeout :为允许等待的时钟节拍.以时钟节拍为单位(5ms)
非0:当等待时间超过timeout*时钟节拍时结束等待状态--变成就绪态
0: 将永远等待直到资源变成可用
err 为错误信息
OS_NO_ERR 调用成功,任务拥有资源或者目标事件发生
OS_TIMEOUT 规定时间内信号量没有发生
OS_ERR_EVENT_TYPE 如果没有传递指针到信号量
OS_ERR_PEND_ISR 如果ISR调用此函数,结果将异常
OS_ERR_PEVENT_NULL 如果 'pevent' 是一个空指针
3 发送信号量
INT8U OSSemPost(OS_EVENT *pevent);
pevent :为信号量指针
总结:
1.OSSemPost 和OSSemPend是成对出现的,在程序OSSemPost 尚未运行到的时候,在等待信号量的OSSemPend是会把当前的任务挂起,直到另外一个任务的OSSemPost 运行完毕将得到信号量。
2.但是可以通过改变OSSemCreate(cnt)里面的值cnt改变这种局面,当cnt不为0时,OSSemPend会马上得到信号量继续运行当前任务至结束,并将cnt的数值减1,直到为0。为0后,只有等其他任务的OSSemPost了。
4 删除信号量函数
OS_EVENT *OSSemDel (OS_EVENT *pevent,INT8U opt, INT8U *err);
pevent :为要删除的信号量指针
opt :为删除条件选项,可以选择只能在已经没有任何任务在
等待该信号量时,才能删除该信号量(OS_DEL_NO_PEND)
;或者,不管有没有任务在等待该信号量,立即删除该信号量
(OS_DEL_ALWAYS),在这种情况下,所有等待该信号量的任
务都立即进入就绪态
err :为错误信息
OS_NO_ERR 调用成功,信号量已被删除;
OS_ERR_DEL_ISR 试图在中断服务子程序中删除信号量;
OS_ERR_INVALID_OPT 没有将opt参数定义为2种合法的参数之一;
OS_ERR_TASK_WAITING 有一个或一个以上的任务在等待信号量;
OS_ERR_EVENT_TYPE pevent不是指向信号量的指针;
OS_ERR_PEVENT_NULL 已经没有可用的OS_EVENT数据结构了。
应用程序如果不需要某个信号量了,那么可以调用函数 OSSemDel 来删除该信号量
邮箱(消息邮箱、消息):
邮箱是信号量的扩展,相当于把一个定义的指针变量从一个任务传递到另一个或多个任务中去,这个指针是先发到邮箱,然后等待任务从邮箱里提取指针,这也就传递了指针指向的具体变量值。
等待邮箱的任务也是可以设置无限等待和等待若干个时钟节拍后任务自动恢复执行。后面的队列,我们也可以看得出它们规律,都有各自的建立,删除,发送,接收,查询等功能函数。
1 创建邮箱函数
OS_EVENT *OSMboxCreate (void *msg);
msg :初始化建立的消息邮箱。如果该指针不为空,建立的消息邮箱将含有消息
返回值:指向分配给所建立的消息邮箱的事件控制块的指针。
2 向邮箱发送消息函数
INT8U OSMboxPost (OS_EVENT *pevent,void *msg);
pevent :消息邮箱的指针
msg :消息指针
3 等待消息邮箱函数
void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err);
用于任务等待消息邮箱,消息通过中断或另外的任务发送给需要的任务
Pevent:指向即将接受消息的消息邮箱的指针。
Timeout :允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的消息时恢复运行。如果该值为零表示任务将持续的等待消息。最大的等待时间为 65,535 个时钟节拍。
Err:指向包含错误码的变量的指针。
OSMboxPend () 函数返回的错误码可能为下述几种:
OS_NO_ERR :消息被正确的接受。
OS_TIMEOUT :消息没有在指定的周期数内送到。
OS_ERR_PEND_ISR : 从中断调用该函数。 虽然规定了不允许从中断调用该函数, 但 uC/OS-Ⅱ仍然包含了检测这种情况的功能。
OS_ERR_EVENT_TYPE :pevent 不是指向消息邮箱的指针。
作业:
1、理解事件的相关工作过程
2、信号量 -- 按键控制LED灯(计数型信号量)
-- 图片滚动和RTC时间显示
用LED灯实现信号量的几种现象--cnt初值为0和不为0,挂起永久等待和一段时 间的等待
3、邮箱 -- 2个按键,发送消息,分别控制LED灯,
--图片滚动显示和RTC时钟显示
触摸屏按键值显示在LCD屏上
操作触摸屏按键
(可以用计数型信号量来计数触摸屏按键次数)