ucosii事件控制块------消息邮箱与消息队列
UCOSII 使用叫做事件控制块(ECB)的数据结构来描述诸如信号量、邮箱(消息邮箱)和消息队列这些事件
#define OS_EVENT_EN (((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u) || (OS_SEM_EN > 0u) || (OS_MUTEX_EN > 0u))
事件控制块类型定义:
typedef struct os_event {
INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_xxxx) */
void *OSEventPtr; /* Pointer to message or queue structure */
INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */
OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ #if OS_EVENT_NAME_EN > 0u
INT8U *OSEventName;
#endif
} OS_EVENT;
消息邮箱:
向邮箱发送消息函数:INT8U OSMboxPost (OS_EVENT *pevent, void *pmsg)其中 pevent 为消息邮箱的指针, msg 为消息指针
该函数先检查消息邮箱结构体成员指针变量OSEventPtr是否为0,若为0,则说明消息邮箱为空,为其赋值pevent->OSEventPtr = pmsg;否则返回对应错误代码。
请求邮箱函数:void *OSMboxPend (OS_EVENT *pevent, INT16U timeout,INT8U *err) 其中 pevent 为请求邮箱指针, timeout 为等待时限, err 为错误信息。
这个函数的主要作用就是查看邮箱指针 OSEventPtr 是否为 NULL,如果不是 NULL 就把邮箱中的消息指针返回给调用函数的任务,然后清空邮箱pevent->OSEventPtr = (void *)0;同时用 OS_NO_ERR 通过函数的参数 err 通知任务获取消息成功。
如果邮箱指针OSEventPtr 是 NULL,则使任务进入等待状态,并引发一次任务调度
创建消息邮箱:OS_EVENT *OSMboxCreate (void *pmsg),
例如:
msg_key=OSMboxCreate((void*)0); //创建邮箱并初始化为空
如果指针不为空,建立的消息邮箱将含有消息
消息队列:
与邮箱相比,消息队列在OS_EVENT结构基础之上添加了一循环队列,可以同时容纳多个消息,而邮箱只能容纳一个。因此,可以将消息队列看作同时接收多条消息的邮箱。
队列控制块类型定义:
typedef struct os_q { /* QUEUE CONTROL BLOCK */
struct os_q *OSQPtr; /* Link to next queue control block in list of free blocks */
void **OSQStart; /* Pointer to start of queue data */
void **OSQEnd; /* Pointer to end of queue data */
void **OSQIn; /* Pointer to where next message will be inserted in the Q */
void **OSQOut; /* Pointer to where next message will be extracted from the Q */
INT16U OSQSize; /* Size of queue (maximum number of entries) */
INT16U OSQEntries; /* Current number of entries in the queue */
} OS_Q;
OSQSize:消息指针数组的大小
OSQEntries:消息指针数组中当前存放的消息指针数量(对应消息数量)
) 创建消息队列函数
创建一个消息队列首先需要定义一指针数组,然后把各个消息数据缓冲区的首地址存
入这个数组中,然后再调用函数 OSQCreate 来创建消息队列。创建消息队列函数 OSQCreate
的原型为: OS_EVENT *OSQCreate(void**start,INT16U size)。其中, start 为存放消息缓冲
区指针数组的地址, size 为该数组大小。该函数的返回值为消息队列指针。
) 请求消息队列函数
请求消息队列的目的是为了从消息队列中获取消息。任务请求消息队列需要调用函数
OSQPend,该函数原型为: void*OSQPend(OS_EVENT*pevent,INT16U timeout,INT8U *err)。
其中, pevent 为所请求的消息队列的指针, timeout 为任务等待时限, err 为错误信息。
下面是函数的部分关键代码:
pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
if (pq->OSQEntries > 0u) { /* See if any messages in the queue */
pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
pq->OSQEntries--; /* Update the number of entries in the queue */
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
pq->OSQOut = pq->OSQStart;
}
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (pmsg); /* Return message received */
}
) 向消息队列发送消息函数
任务可以通过调用函数 OSQPost 或 OSQPostFront 两个函数来向消息队列发送消息。函数 OSQPost 以 FIFO( 先进先出)的方式组织消息队列,函数 OSQPostFront 以 LIFO(后
进先出)的方式组织消息队列。这两个函数的原型分别为: INT8U OSQPost(OS_EVENT*pevent,void *msg)和 INT8U OSQPost(OS_EVENT*pevent,void*msg)。
其中, pevent 为消息队列的指针, msg 为待发消息的指针。
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
OS_EXIT_CRITICAL();
return (OS_ERR_Q_FULL);
}
*pq->OSQIn++ = pmsg; /* Insert message into queue */
pq->OSQEntries++; /* Update the nbr of entries in the queue */
if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
pq->OSQIn = pq->OSQStart;
}
注:消息队列用作消息缓冲区是明智的(适合于进程通信),可要是用它来作为接收批量数据的数据缓冲区就不行了,因为ucos中的消息队列每次只能取出一条消息和每次只能放入一条消息。
ucosii事件控制块------消息邮箱与消息队列的更多相关文章
- RTX——第16章 消息邮箱
以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 前面几个章节主要给大家讲解了任务间的同步和资源共享机制,本章节为大家讲解任务间的通信机制消息邮箱,RTX ...
- μC/OS-II 任务的同步与通信 --- 消息邮箱
简介 如果把数据缓冲区的指针赋给一个事件控制块的成员 OSEventPrt,同时使事件控制块的成员 OSEventType 为常数 OS_EVENT_TYPE_MBOX,则该事件控制块就叫做消息邮箱, ...
- FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组,任务消息邮箱
以下基础内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Not ...
- UCOS-2 消息邮箱与队列
一个有趣的网络解释: 信号量就是中央政府发给官人做一方大员的官印,有很多种官印但是不能一印多发,得到官印者才能掌权鱼肉一方百姓(任务得到信号量才能运行),否则你就只要等官跑官.(当然官印也可随时被政府 ...
- uCOS-II消息邮箱的使用
具体使用方法与信号量的方式大同小易. 首先建立一个OS_EVENT结构体(事件控制块)的指针: OS_EVENT *MSBOX; 然后建立消息邮箱,返回值为事件控制块的指针: MSBO ...
- MSMQ-发送消息到远程专用队列 实例
目录 一:MSMQ的一些理论上的知识 二:队列类型(Queue Type) 三:安装消息队列 四:在C#中Messagequeue class 五:MSMQ-发送消息到远程专用队列 六:例子 一. ...
- 【iCore4 双核心板_uC/OS-II】例程八:消息邮箱
一.实验说明: 消息邮箱是uC/OS-II中的另一种通信机制,可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量.通常该指针指向一个包含了“消息”的特定数据结构. 二.实验截图: ...
- 17.3-uC/OS-III消息管理(消息队列使用)
多值信号量和和互斥信号量主要用来标志事件是否发生和协调资源的访问.如果要给资源赋予内容进行传递, 信号量就力有所不及了.这时候就需要用到 uC/OS 操作系统的另一个内核机制了,那就是消息队列. 2. ...
- redis 的消息订阅和消息队列的功能比较
消息队列常用的有 rabitMQ.kafka等.缓存服务器 redis 也可以做消息队列使用,他们的特点对比如下 消息协议: 消息队列支持包括AMQP,MQTT,Stomp等,并且支持 JMS 规范 ...
随机推荐
- 关于C++ 中POD类型的解析
转自: http://liuqifly.spaces.live.com/blog/cns!216ae3a149106df9!221.entry (C++-98:1.8;5)给出的定义:将对象的各字节拷 ...
- (转)Unity中武器与人物的碰撞检测
自:http://blog.csdn.net/Monzart7an/article/details/24435843 目前来说有三种思路,其实前两种算变种了: 1.动画关键帧回调 + 范围检测. 这个 ...
- 免费的HTML模板引导 - lonely
在线演示 本地下载 今天和大家分享另一款模板-Lonely.它可以被用在一些个人或者类似简单一些的网站上,动画效果的滚动非常特别!
- Android动态加入控件约束位置
用LayoutParams: RelativeLayout insertLayout = (RelativeLayout)view1.findViewById(R.id.screen);//scree ...
- 上传app store 应用指南链接--2
http://www.docin.com/p-166876874.html http://jamesli.cn/blog/?p=955 http://www.adobe.com/devnet/flas ...
- Nhibernate Criteria 多个or条件查询
sql: select * from table t where (t.name like '%张三%' or t.schoolName like '%张三%' or t.cityname like ...
- 【剑指offer】二分查找二维数组
1 2 3 4 5 6 7 8 9 3 3 1 2 3 4 5 6 7 8 9 10 3 3 12 2 3 4 5 6 7 8 9 10 例子输出: Yes No No 时间限制:1 秒 内存限制:3 ...
- 1z0-052 q209_7
7: In which of the scenarios will the DBA perform recovery? (Choose all that apply.) A.The alert log ...
- [Done]BTrace使用小记
项目上线,发现集群机器每隔1小时会准时进行fullgc,JMC中显示了System.gc()触发了fullgc: 代码搜了一下自然是搜不到显示调用这个代码的(谁会这么干!拍死!!!)依赖jar包中到是 ...
- python之函数用法all
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法all #all(iterable) #说明:如果iterable的所有元素不为0.' ...