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事件控制块------消息邮箱与消息队列相关推荐

  1. ucosii中消息队列、消息邮箱、信号量的区别

    1.用信号量进行行为同步时,只能提供同步的时刻信息,不能提供内容信息.若被控制方要求得到控制方的内容信息时,可以使用消息邮箱或消息队列. 2.但由于消息邮箱里只能存放一条消息,所以使用消息邮箱进行任务 ...

  2. UCOSII中消息邮箱的使用方法详解

    UCOSII中到底如何使用邮箱来进行任务间通信? 前言:什么是行为同步,什么是资源同步? 行为同步: 资源同步: 1.在中断服务程序中(ISR)可不可以发送消息? 在ISR中,是可以发送消息的.类似的 ...

  3. uCOS-II消息邮箱的相关操作函数

    定位到uCOS-II/Source/os_mbox.c,该文件是消息邮箱管理的相关操作函数.   任务与任务之间需要数据传递,那么为了适应传递的数据的不同类型,可以建立一个缓冲区(void*类型可以接 ...

  4. (uC/OS-II学习笔记) 消息邮箱消息队列

    原文出处: http://www.cnblogs.com/hebaichuanyeah 与信号量一样,消息邮箱与消息列队都是一种事件块. 消息邮箱可以在任务间实现信息传递. 比如,在任务1中发送一条消 ...

  5. UCOS你问我答系列之消息邮箱详解

    邮箱是UCOS的一种通讯机制, 它可以使一个任务或者一个中断服务程序向另一个任务发送一个void *OSEventPtr指针变量,该指针指向一个特定的数据结构.即通过该指针传递消息. 本文使用的UCO ...

  6. FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组,任务消息邮箱

    以下基础内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Not ...

  7. freeRTOS学习 — 消息邮箱

    1.freeRTOS中的消息邮箱 freeRTOS实现的消息邮箱是基于任务通知方式而实现的. 采用这种方式有什么优势呢? 从官方给出的测试报告中有说明到,唤醒由于信号量和事件标志组而处于阻塞态的任务, ...

  8. RT-Thread快速入门-消息邮箱

    首发,公众号[一起学嵌入式] 前面几篇文章介绍了线程(任务)间的同步机制:信号量.互斥量.事件集.接下来我们学习线程(任务)之间的通信机制. 一般来说,RTOS 均会提供两种线程间通信的机制:消息邮箱 ...

  9. uC/OS-II消息邮箱及其操作

    如果要在任务与任务之间传递一个数据,可以用消息邮箱,它的原理是在存储器中建立一个数据缓冲区,然后就以这个缓冲区为中介来实现任务间的数据传递. 一. 消息邮箱的操作 1. 创建消息邮箱 OS_EVENT ...

最新文章

  1. 使用MS VS的命令来编译C++程序
  2. PostgreSQL调研
  3. Dapper的基本使用 [转]
  4. 中国航空航天产业创新发展态势及市场规模分析报告2021-2027年版
  5. http81僵尸网络预警:专门攻击摄像头,国内5万台设备已沦陷
  6. 给数据表中的字段添加约束
  7. 【MFC系列-第24天】梯形分页和蝴蝶QQ宠物的实现
  8. 安徽省2012年下半年计算机水平考试(二级 c语言程序设计),安徽省计算机等级二级考试真题C语言2012年12月...
  9. 收藏 | 聊聊 GPU 的计算能力上限
  10. WSUS离线导入更新包
  11. Unity初级坦克大战游戏实现(Battle Tank)带工程源码资源包(二)
  12. springcloud 微服务的组成部分
  13. python三人同行七十稀_三人同行(三人同行什么意思)
  14. 初二因式分解奥数竞赛题_初中数学因式分解含答案竞赛题精选
  15. Spark学习-DAY1
  16. 如何抢走亚马逊竞品手上的客户和流量?
  17. GStreamer appsrc 等插件实现视频音频混流,录制和推流
  18. Java classloader 常见问题及解决方法
  19. Vue中 引入使用 vue-video-player 实现音视频播放
  20. 使用 Steam++ 快速访问 Github

热门文章

  1. linux下查找网口_Linux查看网络端口
  2. 南航计算机硬件实验,南航80X86微机原理及接口技术实验指导书.pdf
  3. swift和python语法区别_Swift 基本语法
  4. Thymeleaf 中js 使用等报错问题
  5. 对机械臂的肩关节与肘关节编码器连接与设置
  6. 更换紧凑型荧光灯管过程
  7. SH-20403AXIS12双轴蓝牙移动框架
  8. TC264信标组 双车组 资源规划 库函数示例
  9. 点击某个a标签,禁止页面自动跳转到该页面的顶部
  10. 行业软件和鸿蒙,华为鸿蒙负责人王成录:育人才,打造国产软件“根”能力