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# 特性(Attribute)(二)
AttributeUsage类是另外一个预定义特性类,它帮助我们控制我们自己的定制特性的使用.它描述了一个定制特性如和被使用. AttributeUsage有三个属性,我们可以把它放置在定制属性 ...
- ECMAScript5之Object学习笔记(三)
第三部分继续... Object.getOwnPropertyDescriptor(obj, prop) 获取一个对象的属性描述符 根据"Own"这个词我们可以猜到,prop只能是 ...
- 项目加入 TFS报错
新建一个项目,然后在解决方案上右击,选择Add solution to source control的时候,总是失败,output窗口中出现的错误信息如下: An error was raised ...
- 【Javascript Demo】根据Email地址跳转到相应的邮箱登录页面
我的初步想法是通过指定的邮箱地址自动查找到对应的邮箱登录页面,但是用数据库.js什么的都有局限性,因为各种各样的邮箱太多了,不能都包含的到,网上找了半天都没有找到满意的答案,自己又想不出方法,只能暂时 ...
- PHPCMS增加投票选项代码
<script src="jquery-1.10.1.js"></script> <tr> <th width="20%&quo ...
- 上传的文件放在SVN服务器的哪个目录下
SVN服务器版本库有两种格式,一种为FSFS,一种为BDB 把文件上传到SVN版本库后,上传的文件不再以文件原来的格式存储,而是被svn以它自定义的格式压缩成版本库数据,存放在版本库中. 如果是FSF ...
- Java多线程(1) 创建
一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下以下这张较为经典的图: Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Threa ...
- atitit.提升开发效率---MDA 软件开发方式的革命(3)----自己主动化建表
atitit.提升开发效率---MDA 软件开发方式的革命(3)----自己主动化建表 1. 建模在后自己主动建表 1 1. 传统上,须要首先建表,在业务编码.. 1 2. 模型驱动建表---很多其它 ...
- js 面向对象式编程
1.声明一个函数,在函数内进行初始化操作,,函数不能有返回值2.把需要的参数传递进去,参数最好以对象形式传入,如果有默认的设置默认参数3.把传入的参数都保存到对象的属性上面4.把初始化操作中需要用到的 ...
- 如何在MyEclipse中建立一个代理服务器
一.什么是 TCP/IP Monitor TCP/IP monitor 是可以监控在某个端口上通过 TCP/IP 协议传送的通信数据的一个工具软件. TCP/IP monitor 工具,通过一些配置, ...