uCOS-II任务间通信之邮箱

R语言使用mlr包创建回归任务、指定回归学习函数为KNN回归模型、网格搜索、交叉验证调节KNN模型的超参数K获取模型最佳的K值、可视化KNN模型的不同K值和MSE指标之间关系图 阅读详情
uCOS-II任务间通信之邮箱
学过信号量之后再来看邮箱,发现它们是非常相似的,甚至有时候邮箱可以当做信号量来使用,邮箱相对信号量而言,只是多传递了一个指针变量。
和信号量很相似,ucos II提供了5个对邮箱进行操作的函数。它们是:
1. 建立一个邮箱 -- OSMboxCreate()
2. 等待一个邮箱中的消息 -- OSMboxPend()
3. 发送一个消息到邮箱中 -- OSMboxPost()
4. 无等待地从邮箱中得到一个消息 -- OSMboxAccept()
5. 查询一个邮箱的状态 -- OSMboxQuery()
使用邮箱之前,必须先建立该邮箱。该操作可以通过调用OSMboxCreate()函数来完成,并且要指定指针的初始值。一般情况下,这个初始值是NULL,但也可以初始化一个邮箱,使其在最开始就包含一条消息。如果使用邮箱的目的是用来通知任务某一个事件已经发生(发送一条消息),那么就要初始化该邮箱为NULL。如果用户用邮箱来共享某些资源,那么就要初始化该邮箱为一个非NULL的指针。在这种情况下,邮箱被当成一个二值信号量使用。

下面来看看创建一个邮箱函数的实现代码:
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. OS_EVENT *OSMboxCreate (void *msg)  
  2. {  
  3.     OS_EVENT *pevent;  
  4.    
  5.    
  6.     OS_ENTER_CRITICAL();  
  7.     pevent = OSEventFreeList;  
  8.     if (OSEventFreeList != (OS_EVENT *)0) {  
  9.         OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;  
  10.     }  
  11.     OS_EXIT_CRITICAL();  
  12.     if (pevent != (OS_EVENT *)0) {  
  13.         pevent->OSEventType = OS_EVENT_TYPE_MBOX;                      //(1)  
  14.         pevent->OSEventPtr  = msg;                                     //(2)  
  15.         OSEventWaitListInit(pevent);  
  16.     }  
  17.     return (pevent);                                                   //(3)  
  18. }  


仔细看看,其实和创建一个信号量的过程几乎是一样的,先申请一个空事件控制块,接着初始化这个事件控制块。最后返回一个指向这个事件控制块的指针。不同之处在于事件控制块的类型被设置成OS_EVENT_TYPE_MBOX(1),以及使用.OSEventPtr域来容纳消息指针。

接着来看看等待邮箱函数实现代码:
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)  
  2. {  
  3.     void  *msg;  
  4.    
  5.     OS_ENTER_CRITICAL();  
  6.     if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {               //(1)  
  7.         OS_EXIT_CRITICAL();  
  8.         *err = OS_ERR_EVENT_TYPE;  
  9.         return ((void *)0);  
  10.     }  
  11.     msg = pevent->OSEventPtr;  
  12.     if (msg != (void *)0) {                                        //(2)  
  13.         pevent->OSEventPtr = (void *)0;                            //(3)  
  14.         OS_EXIT_CRITICAL();  
  15.         *err = OS_NO_ERR;  
  16.     } else if (OSIntNesting > 0) {                                 //(4)  
  17.         OS_EXIT_CRITICAL();  
  18.         *err = OS_ERR_PEND_ISR;  
  19.     } else {  
  20.         OSTCBCur->OSTCBStat |= OS_STAT_MBOX;                       //(5)  
  21.         OSTCBCur->OSTCBDly   = timeout;  
  22.         OSEventTaskWait(pevent);  
  23.         OS_EXIT_CRITICAL();  
  24.         OSSched();  
  25.         OS_ENTER_CRITICAL();  
  26.         if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {             //(6)  
  27.             OSTCBCur->OSTCBMsg      = (void *)0;  
  28.             OSTCBCur->OSTCBStat     = OS_STAT_RDY;  
  29.             OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;  
  30.             OS_EXIT_CRITICAL();  
  31.             *err                    = OS_NO_ERR;  
  32.         } else if (OSTCBCur->OSTCBStat & OS_STAT_MBOX) {           //(7)  
  33.             OSEventTO(pevent);                                     //(8)  
  34.             OS_EXIT_CRITICAL();  
  35.             msg                     = (void *)0;                   //(9)  
  36.             *err                    = OS_TIMEOUT;  
  37.         } else {  
  38.             msg                     = pevent->OSEventPtr;          //(10)  
  39.             pevent->OSEventPtr      = (void *)0;                   //(11)  
  40.             OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;               //(12)  
  41.             OS_EXIT_CRITICAL();  
  42.             *err                    = OS_NO_ERR;  
  43.         }  
  44.     }  
  45.     return (msg);  
  46. }  

同样,它和OSSemPend()也很相似,说白了就是先看有没有有用的消息,要是没有,就把该任务挂起来。
 OSMboxPend()首先检查该事件控制块是由OSMboxCreate()函数建立的(1)。当.OSEventPtr域是一个非NULL的指针时,说明该邮箱中有可用的消息(2)。这种情况下,OSMboxPend()函数将该域的值复制到局部变量msg中,然后将.OSEventPtr置为NULL(3)。这正是我们所期望的,也是执行OSMboxPend()函数最快的路径。
如果此时邮箱中没有消息是可用的(OSEventPtr域是NULL指针),OSMboxPend()函数检查它的调用者是否是中断服务子程序(4)。象OSSemPend()函数一样,不能在中断服务子程序中调用OSMboxPend(),因为中断服务子程序是不能等待的。这里的代码同样是为了以防万一。但是,如果邮箱中有可用的消息,即使从中断服务子程序中调用OSMboxPend()函数,也一样是成功的。
如果邮箱中没有可用的消息,OSMboxPend()的调用任务就被挂起,直到邮箱中有了消息或者等待超时(5)。当有其它的任务向该邮箱发送了消息后(或者等待时间超时),这时,该任务再一次成为最高优先级任务,OSSched()返回。这时,OSMboxPend()函数要检查是否有消息被放到该任务的任务控制块中(6)。如果有,那么该次函数调用成功,对应的消息被返回到调用函数。
发送一个消息到邮箱中OSMboxPost()的代码如下:
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. INT8U OSMboxPost (OS_EVENT *pevent, void *msg)  
  2. {  
  3.     OS_ENTER_CRITICAL();  
  4.     if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {            //(1)  
  5.         OS_EXIT_CRITICAL();  
  6.         return (OS_ERR_EVENT_TYPE);  
  7.     }  
  8.     if (pevent->OSEventGrp) {                                   //(2)  
  9.         OSEventTaskRdy(pevent, msg, OS_STAT_MBOX);              //(3)  
  10.         OS_EXIT_CRITICAL();  
  11.         OSSched();                                              //(4)  
  12.         return (OS_NO_ERR);  
  13.     } else {  
  14.         if (pevent->OSEventPtr != (void *)0) {                  //(5)  
  15.             OS_EXIT_CRITICAL();  
  16.             return (OS_MBOX_FULL);  
  17.         } else {  
  18.             pevent->OSEventPtr = msg;                           //(6)  
  19.             OS_EXIT_CRITICAL();  
  20.             return (OS_NO_ERR);  
  21.         }  
  22.     }  
  23. }  

发送一个消息到邮箱和发送一个信号量也很相似,就是查看有没有任务在等待这个消息,如果有就把那个任务从睡眠态拉回就绪态。
代码的详细解释如下:

检查了事件控制块是否是一个邮箱后(1),OSMboxPost()函数还要检查是否有任务在等待该邮箱中的消息(2)。如果事件控制块中的OSEventGrp域包含非零值,就暗示着有任务在等待该消息。这时,调用OSEventTaskRdy()将其中的最高优先级任务从等待列表中删除(3),加入系统的就绪任务列表中,准备运行。然后,调用OSSched()函数(4),检查该任务是否是系统中最高优先级的就绪任务。如果是,执行任务切换[仅当OSMboxPost()函数是由任务调用时],该任务得以执行。如果该任务不是最高优先级的任务,OSSched()返回,OSMboxPost()的调用函数继续执行。如果没有任何任务等待该消息,指向消息的指针就被保存到邮箱中(6)(假设此时邮箱中的指针不是非NULL的(5))。这样,下一个调用OSMboxPend()函数的任务就可以立刻得到该消息了。


基于Transformer的股票市场多因子量化选股模型,深度解析:基于Transformer的股票市场多因子量化选股模型 传统多因子模型通常采用线性回归、岭回归或Lasso回归来估计因子权重,其核心假设是因子与未来收益之间存在线性关系。然而,现实中的股票市场具有典型的非线性、非平稳和高噪声特征。卷积神经网络(CNN)擅长提取局部特征,但难以捕捉全市场股票之间的全局依赖关系;循环神经网络(RNN)及其变体LSTM虽然能处理时间序列,但存在梯度消失问题且难以并行计算。Transformer的self-attention机制能够:直接建模任意两只股票之间的相关性动态计算因子权重而非静态线性组合。 阅读详情

相关推荐

决策大模型与生成式大模型有何不同?一文拆解技术框架与落地路径

大模型技术正从内容生成走向复杂场景的智能决策。与生成式大模型拟合概率分布不同,决策大模型以序列决策为核心,融合强化学习机制,在动态环境中感知反馈、持续修正行动路径。其技术框架涵盖语义理解、规划推理与闭环决策,并通过世界模型进行低成本仿真推演,显著提升供应链调度、物流排程等场景的应对效率。实际落地时需结合传统优化算法与人工兜底,构建“语义先导+数值寻优”的分层架构,才能平衡精度与稳定性。这篇内容拆解决策大模型的技术组成、落地路径与常见误区,为企业智能化转型提供可参考的实践框架。

weixin_29057163的博客 188

UCOSII消息队列

消息队列介绍 消息队列是µC/OS-II中另一种通讯机制,它可以使一个任务或者中断服务子程序向另一个任务发送以指针方式定义的变量。因具体的应用有所不同,每个指针指向的数据结构变量也有所不同。为了使用µC/OS-II的消息队列功能,需要在OS_CFG.H 文件中,将OS_Q_EN常数设置为1,并且通过常数OS_MAX_QS来决定µC/OS-II支持的最多消息队列数。 OSQCreate()建立消息队列函数 1、主要作用:该函数用于建立一个消息队列。任务或中断可以通过消息队列向一个或多个任务发送消息。消息

小吕的博客 1892

高分三号SAR影像超精细条带数据预处理实战:从原始数据到地理编码的完整操作指南

本文提供了高分三号SAR影像超精细条带数据预处理的完整实战指南。详细介绍了从原始数据导入、多视处理、滤波去噪、DEM准备到地理编码与辐射定标的完整流程,帮助用户利用SARscape软件将原始SAR数据转化为可用于分析的地理编码产品。

tree8的博客 577

STM32 UCOSII 邮箱的学习和使用

介绍UCOSII邮箱的使用和程序中注意的要点

SuperShuiShui’博客 4784

从触觉到视觉:GelSight传感器的工作原理与实战应用指南

本文深入解析了GelSight光学触觉传感器的核心工作原理,它通过将物理接触转化为视觉图像,为机器人提供了高精度的触觉感知。文章详细介绍了其在工业微观缺陷检测、机器人灵巧操作等领域的实战应用,并提供了从系统搭建到算法开发的完整指南,帮助工程师将这一前沿技术落地于实际项目。

solidity8miner的博客 939

卸载重装Ubuntu22.04双系统

先说一下写此篇文章的背景吧,我在Windows下配置了三个cornerNet深度学习环境分别是cuda10.3(显卡版本太高不支持),cuda11.3(配置后偶然看到一篇说这个版本win下只能用CPU跑),最后是cuda11.1终究还是没能跑通代码,因为它的代码是在Liunx系统写的,就想着装个Ubuntu试试看,在网上看说一般软件不要装太高版本,我就下载了470版的显卡驱动,跟着步骤升级了系统内核,结果第二天开机Ubuntu就崩了,开机黑屏左上角只有一道横杠显示,只能按ctrl+shift+f5进入命令窗

编程小白的博客 8106

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

UCOS中到底如何使用邮箱来进行任务间通信? 1、在中断服务程序中(ISR)可不可以发送消息? 在ISR中,是可以发送消息的。类似的,也可以发送信号量、消息队列等。这里需要注意的一点是不能在ISR中请求消息,即不能调用OSXXXPend()函数。原因是在该函数中首先要判断中断的嵌套层数,如果当前的嵌套层数大于0,那么会直接返回空,如下图(UCOSII源码:OSXXXPend()函数) 这里另外说一下,判断某个函数能否在中断中使用,这里需要去看源代码,在该函数真正执行相应动作之前都会先进行一系列的判断操作,

栀忆 6956

beegfs源码分析

BeeGFS的客户端是由一个内核模块和两个系统服务组成的,这里咱们主要分析内核模块。由于BeeGFS的目录树解析,是在父目录DEntry里找子目录或文件DEntry,逐级迭代完成的,所以在Mount文件系统时,须要从管理节点获取根元数据节点的ID,而后再向根元数据节点查询根目录的DEntry的信息,为后续的目录解析打下基础。获取类似/data/beeond/data/dentries/38/51/root/#fSiDs#/文件fileId的父路径。1.1 FileID的生成。Session网络消息。

wfzy的博客 1913

uC/OS-II 函数之邮箱管理相关函数

本文介绍邮箱管理相关的函数:OSMboxCreate()建立一个邮箱,OSMboxDel()删除一个邮箱,OSMboxPend()等待邮箱中的消息,OSMboxPost()向邮箱发送一则消息,OSMboxQuery()查询一个邮箱的状态邮箱管里介绍邮箱是µC/OS-II中另一种通讯机制,它可以使一个任务或者中断服务

peace唠叨 1804

lammps教程:MS转data文件出错原因分析及解决办法

使用ms建模是lammps建模的一种重要方法,但是ms建模转换为data过程中经常会出现各种各样的错误。 ms模型转data文件流程分两部分,一是ms建模、forcite设置力场并导出car文件,二是msi2lmp将car转为data文件。 任何一个环节出错都会导致无法得到data文件,最容易出错的是forcite力场设置环节。 forcite力场设置出错原因有很多,一个原因是缺乏某类原子的力场参数。 msi2lmp软件只能转换cvff或pcff力场的car文件,因此,如果力场中不包含某类原子的参数,在设置

lammps_jiayou的博客 5062

基于YOLOv8深度学习的夜视行人检测系统:UI界面 + YOLOv8 + 数据集的实现

为了解决这一问题,基于深度学习的行人检测技术,尤其是YOLO(You Only Look Once)系列算法,成为了一个有效的解决方案。本文将详细介绍如何构建一个夜视行人检测系统,利用YOLOv8模型实现高效的行人检测,并设计用户友好的界面以便于使用。本博客详细介绍了如何构建一个基于深度学习的夜视行人检测系统,包括数据准备、YOLOv8模型训练、用户界面设计和实时监控模块的实现。为了将数据集转换为YOLO格式,我们需要确保每个图像文件都有一个对应的标签文件,标签文件中包含行人的边界框信息。

YOLO 1172

uCOSii消息邮箱管理

消息邮箱主要用于中断和任务之间进行邮件传递,或者是在任务与任务之间进行邮件交换。 OSMboxCreate(); OSMboxPost(); OSMboxPostOpt(); OSMboxAccept(); OSMboxPend(); OSMboxDel(); OSMboxQuery();

weixin_42550185的博客 2650

基于Simulink的四足机器人楼梯攀爬仿真模型

构建一个基于Simulink的四足机器人楼梯攀爬仿真模型,旨在模拟四足机器人在面对楼梯等障碍时的运动控制和稳定性调整。以下是一个详细的步骤指南,帮助你从零开始创建这样一个仿真模型。

xiaoheshang_123的博客 247

uCOS-II任务间通信之邮箱 [转载]

uCOS-II任务间通信之邮箱 学过信号量之后再来看邮箱,发现它们是非常相似的,甚至有时候邮箱可以当做信号量来使用,邮箱相对信号量而言,只是多传递了一个指针变量。 和信号量很相似,ucos II提供了5个对邮箱进行操作的函数。它们是: 1. 建立一个邮箱 -- OSMboxCreate() 2. 等待一个邮箱中的消息 -- OSMboxPend() 3. 发送一个消息到邮箱中 -- OS

我的博客 4272

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

UCOS-II任务间通信(信号量、邮箱、消息队列)

保护任务之间的共享数据和提供任务之间的通讯方法: 利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭和打开中断,这可以用于多任务或者任务和ISR共享某些数据时可以采用这种方法。 利用OSSchedLock()和OSSchedUnlock()对uC/OS-II中的任务调度器上锁和开锁。 利用信号量、邮箱和消息队列。   一个任务或者中断服务子程序

_CJM的博客 9301

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

一步一步教你使用uCOS-II

第一篇 UCOS介绍 第一篇 UCOS介绍   这个大家都知道。呵呵。考虑到咱们学习的完整性还是在这里唠叨一下。让大家再熟悉一下。高手们忍耐一下吧! uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和很多商业操作

overflyme的博客 7万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

uCOS-II邮箱和消息队列

转载 http://blog.youkuaiyun.com/humchx/article/details/4536229      uCOS-II邮箱和消息队列  分类: 嵌入式 2009-09-09 16:58 1585人阅读 评论(3) 收藏 举报    1、 uCOS-II邮箱和消息队列            邮箱和消息队列是uCOS-II中任务间的通讯机制,它可以使一个任务或

luy3728000的轨迹 1424

关于ucosii的邮箱

 ucos II 任务间 通信之四:邮箱   学过信号量之后再来看邮箱,发现他们是非常相似的,甚至有时候邮箱可以当做信号量来使用,邮箱相对信号量而言,只是多传递了一个指针变量。和信号量很相似,ucos II提供了5个对邮箱进行操作的函数。它们是:1. 建立一个邮箱,OSMboxCreate()2. 等待一个邮箱中的消息,OSMboxPend()3. 发送一个消息到邮箱中,OSMboxPost()4...

SUN1_SHINE2的博客 1116

uCOS-II任务间通信之事件控制块

uCOS-II任务间通信之事件控制块 信号、邮箱、消息队列都是需要先创建才能使用的,创建以上三者需要用到事件控制块这一东西。 那什么是事件控制块呢? 可以这样理解,前面学习我们已经知道,创建一个任务需要给这个任务分配一个任务控制块,这个任务控制块存储着关于这个任务的重要信息。那么,事件控制块就好比任务里的任务控制块。它存储着这个事件的重要信息,我们说创建一个事件(信号,邮箱,消息队列),其本

root_robot的博客 644

ucos-II 任务间通信源码分析

ucos-II 2.0版本的任务间通信提供消息邮箱和消息队列两种机制,都基于内核的事件控制块机制实现。 消息邮箱 消息邮箱主要函数分析: 建立一个邮箱 OSMboxCreate:初始化一个OS_EVENT_TYPE_MBOX类型的事件块; 向邮箱发送一个消息 INT8U  OSMboxPost (OS_EVENT *pevent, void *msg),该函数调用OS_EventTaskR...

Fred's Note 769

从零构建基于uCOS-II的智能环境响应系统:任务调度与PWM控制的深度实践

本文详细介绍了基于STM32F407和uCOS-II实时操作系统构建智能环境响应系统的完整实践。重点解析了任务调度策略、邮箱通信机制以及PWM占空比控制技术,通过精密算法实现环境数据采集与智能调控,为嵌入式开发者提供了一套可复用的多任务系统设计框架。

data3的博客 1070

uC/OS 的消息邮箱——uC/OS学习笔记(五)

1.简介    在多任务操作系统中,常常需要在任务与任务之间通过传递一个数据(也叫做“消息”)的方式进行通信。为了实现这个目的,可以在内存中创建一个存储空间作为该数据的缓冲区。    如果把这个缓冲区叫做消息缓冲区,那么在任务间传递数据的一个简单方法就是传递消息缓冲区的指针。因此,用来传递消息缓冲区指针的数据结构叫做消息邮箱。 2.消息邮箱的操作    a)声明消息邮箱

yin的博客 2272

hjr-嵌入式:ucos-II 信号量、互斥信号量、消息邮箱

因为ucos-II是基于多任务的操作系统 本节说一下任务中很重要的三个概念 在之前先科普几个重要函数: (1)OSStart();:操作系统多任务启动 (2)OSinit()l:操作系统全局变量,数据结构初始化,建立空闲、统计、定时任务 (1)创建了几个用户任务,优先级 OSTaskCreate(任务处理函数首地址指针,任务处理函数传参,任务分配的堆栈栈顶指针,任务优先级号); ...

hjr的博客 1285

uCOS-II 总结

1、任务调度 1.调度 uCOS-II的任务由任务控制块管理,在任务每个循环的末尾通过调用OSTimeDly()或者OSTimeDlyHMSM()来将当前任务从任务就绪表移除,并将该任务控制块内OSTCBDly赋予新值,然后进行一次任务调度让出CPU控制权。 uCOS-II含有时钟节拍,时钟节拍在开中断的情况下定时触发时钟节拍中断,时钟节拍中断遍历任务控制块链表并将每个任务控制块内的OSTCBDl...

风拂寒雪_我的博客 1798

UCOS II 事件初始化 OS_InitEventList 源码分析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34074740的博客 252

转:一步一步教你使用uCOS-II

第一篇 UCOS介绍 第一篇 UCOS介绍 这个大家都知道。呵呵。考虑到咱们学习的完整性还是在这里唠叨一下。让大家再熟悉一下。高手们忍耐一下吧! uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和很多商业操作系...

anlingjue0465的博客 507
上一篇: uCOS-II任务间通信之信号量
下一篇: uCOS-II内核之任务控制块
root_robot
博客等级 码龄10年 97粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值