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 > 0uINT8U *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:消息指针数组中当前存放的消息指针数量(对应消息数量)
1) 创建消息队列函数
创建一个消息队列首先需要定义一指针数组,然后把各个消息数据缓冲区的首地址存
入这个数组中,然后再调用函数 OSQCreate 来创建消息队列。创建消息队列函数 OSQCreate
的原型为: OS_EVENT *OSQCreate(void**start,INT16U size)。其中, start 为存放消息缓冲
区指针数组的地址, size 为该数组大小。该函数的返回值为消息队列指针。
2) 请求消息队列函数
请求消息队列的目的是为了从消息队列中获取消息。任务请求消息队列需要调用函数
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 */}
3) 向消息队列发送消息函数
任务可以通过调用函数 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事件控制块------消息邮箱与消息队列相关推荐
- ucosii中消息队列、消息邮箱、信号量的区别
1.用信号量进行行为同步时,只能提供同步的时刻信息,不能提供内容信息.若被控制方要求得到控制方的内容信息时,可以使用消息邮箱或消息队列. 2.但由于消息邮箱里只能存放一条消息,所以使用消息邮箱进行任务 ...
- UCOSII中消息邮箱的使用方法详解
UCOSII中到底如何使用邮箱来进行任务间通信? 前言:什么是行为同步,什么是资源同步? 行为同步: 资源同步: 1.在中断服务程序中(ISR)可不可以发送消息? 在ISR中,是可以发送消息的.类似的 ...
- uCOS-II消息邮箱的相关操作函数
定位到uCOS-II/Source/os_mbox.c,该文件是消息邮箱管理的相关操作函数. 任务与任务之间需要数据传递,那么为了适应传递的数据的不同类型,可以建立一个缓冲区(void*类型可以接 ...
- (uC/OS-II学习笔记) 消息邮箱消息队列
原文出处: http://www.cnblogs.com/hebaichuanyeah 与信号量一样,消息邮箱与消息列队都是一种事件块. 消息邮箱可以在任务间实现信息传递. 比如,在任务1中发送一条消 ...
- UCOS你问我答系列之消息邮箱详解
邮箱是UCOS的一种通讯机制, 它可以使一个任务或者一个中断服务程序向另一个任务发送一个void *OSEventPtr指针变量,该指针指向一个特定的数据结构.即通过该指针传递消息. 本文使用的UCO ...
- FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组,任务消息邮箱
以下基础内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Not ...
- freeRTOS学习 — 消息邮箱
1.freeRTOS中的消息邮箱 freeRTOS实现的消息邮箱是基于任务通知方式而实现的. 采用这种方式有什么优势呢? 从官方给出的测试报告中有说明到,唤醒由于信号量和事件标志组而处于阻塞态的任务, ...
- RT-Thread快速入门-消息邮箱
首发,公众号[一起学嵌入式] 前面几篇文章介绍了线程(任务)间的同步机制:信号量.互斥量.事件集.接下来我们学习线程(任务)之间的通信机制. 一般来说,RTOS 均会提供两种线程间通信的机制:消息邮箱 ...
- uC/OS-II消息邮箱及其操作
如果要在任务与任务之间传递一个数据,可以用消息邮箱,它的原理是在存储器中建立一个数据缓冲区,然后就以这个缓冲区为中介来实现任务间的数据传递. 一. 消息邮箱的操作 1. 创建消息邮箱 OS_EVENT ...
最新文章
- 使用MS VS的命令来编译C++程序
- PostgreSQL调研
- Dapper的基本使用 [转]
- 中国航空航天产业创新发展态势及市场规模分析报告2021-2027年版
- http81僵尸网络预警:专门攻击摄像头,国内5万台设备已沦陷
- 给数据表中的字段添加约束
- 【MFC系列-第24天】梯形分页和蝴蝶QQ宠物的实现
- 安徽省2012年下半年计算机水平考试(二级 c语言程序设计),安徽省计算机等级二级考试真题C语言2012年12月...
- 收藏 | 聊聊 GPU 的计算能力上限
- WSUS离线导入更新包
- Unity初级坦克大战游戏实现(Battle Tank)带工程源码资源包(二)
- springcloud 微服务的组成部分
- python三人同行七十稀_三人同行(三人同行什么意思)
- 初二因式分解奥数竞赛题_初中数学因式分解含答案竞赛题精选
- Spark学习-DAY1
- 如何抢走亚马逊竞品手上的客户和流量?
- GStreamer appsrc 等插件实现视频音频混流,录制和推流
- Java classloader 常见问题及解决方法
- Vue中 引入使用 vue-video-player 实现音视频播放
- 使用 Steam++ 快速访问 Github
热门文章
- linux下查找网口_Linux查看网络端口
- 南航计算机硬件实验,南航80X86微机原理及接口技术实验指导书.pdf
- swift和python语法区别_Swift 基本语法
- Thymeleaf 中js 使用等报错问题
- 对机械臂的肩关节与肘关节编码器连接与设置
- 更换紧凑型荧光灯管过程
- SH-20403AXIS12双轴蓝牙移动框架
- TC264信标组 双车组 资源规划 库函数示例
- 点击某个a标签,禁止页面自动跳转到该页面的顶部
- 行业软件和鸿蒙,华为鸿蒙负责人王成录:育人才,打造国产软件“根”能力