uCOSii消息邮箱管理

news2024/11/24 3:22:55

uCOSii消息邮箱管理 (MESSAGE MAILBOX MANAGEMENT)

消息邮箱主要用于中断和任务之间进行邮件传递,或者是在任务与任务之间进行邮件交换。

1、消息邮箱管理重点需要了解下面几个函数

消息邮箱指针=OSMboxCreate(消息邮箱数据块指针) 建立并初始化一个消息邮箱,在初始化时,通常将“消息邮箱数据块指针”设置为0,,如:MailBoxes_Event = OSMboxCreate( (void*)0 );

OSMboxAccept(消息邮箱指针)返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

OSMboxPend(消息邮箱指针,0,&err);*per=OS_ERR_NONE,且返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

OSMboxPost(消息邮箱指针pevent, 消息邮箱数据块指针); 返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

OSMboxPostOpt(消息邮箱指针pevent, 消息邮箱数据块指针, opt) 返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

OSMboxDel() 删除消息邮箱(消息邮箱指针、删除条件、出错代码指针)

OSMboxQuery() 查询一个邮箱的当前状态(信号量指针、状态数据结构指针)

2、OSMboxPost (OS_EVENT  *pevent,  void *pmsg)发送邮件

//函数功能:返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

//注意:为了能够判断消息邮箱是否发送成功,最好使用两个或两个以上的邮箱数据块地址,防止发送过快,导致消息邮箱发送时出现漏发现象;

// pevent为消息邮箱的指针

//pmsg是指向消息邮箱的数据块地址

INT8U  OSMboxPost (OS_EVENT  *pevent,

                   void      *pmsg)

{

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

{//消息邮箱的指针为0

      return (OS_ERR_PEVENT_NULL);

}

if (pmsg == (void *)0)

{//消息邮箱的数据块地址0

return (OS_ERR_POST_NULL_PTR);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

 {//该事件类型不是消息邮箱

        return (OS_ERR_EVENT_TYPE);

}

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

///发现消息邮箱挂起的任务” ///

if (pevent->OSEventGrp != 0u)

{//查询是否有消息邮箱挂起的任务,若有,则立即发送邮件

        (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);

        //pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

        return (OS_ERR_NONE);

}

///没有发现消息邮箱挂起的任务” ///

if (pevent->OSEventPtr != (void *)0)//查询邮箱中的内容是否被接收

{//上次发送的消息邮箱中的内容没有被读取,取消发送邮件

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_MBOX_FULL);//没有执行发送消息邮箱,就退出了

}

/上次发送的消息邮箱中的内容已经被读取/

pevent->OSEventPtr = pmsg;

//pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

//pmsg是指向消息邮箱的数据块地址

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

return (OS_ERR_NONE); //执行发送消息邮箱后,才退出

}

3、OSMboxPostOpt (OS_EVENT  *pevent, void *pmsg,INT8U opt)

opt = OS_POST_OPT_BROADCAST=0x01,群发邮件

opt! = OS_POST_OPT_BROADCAST=0x01,点对点发送邮件

//函数功能:返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

//注意:为了能够判断消息邮箱是否发送成功,最好使用两个或两个以上的邮箱数据块地址,防止发送过快,导致消息邮箱发送时出现漏发现象;

// pevent为消息邮箱的指针

//pmsg是指向消息邮箱的数据块地址

//opt = OS_POST_OPT_BROADCAST=0x01 群发邮件

// opt! = OS_POST_OPT_BROADCAST=0x01, 点对点发送邮件

//opt &OS_POST_OPT_NO_SCHED==0,需要执行任务调度

INT8U  OSMboxPostOpt (OS_EVENT  *pevent,

                      void      *pmsg,

                      INT8U      opt)

{

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

{//消息邮箱的指针为0

        return (OS_ERR_PEVENT_NULL);

    }

if (pmsg == (void *)0)

{//消息邮箱的数据块地址为0

        return (OS_ERR_POST_NULL_PTR);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

{//该事件类型不是消息邮箱

        return (OS_ERR_EVENT_TYPE);

}

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

///发现消息邮箱挂起的任务” ///

if (pevent->OSEventGrp != 0u)

{//查询是否有消息邮箱挂起的任务

        if ((opt & OS_POST_OPT_BROADCAST) != 0x00u)//群发邮件

{

            while (pevent->OSEventGrp != 0u)

{//循环查询是否有消息邮箱挂起的任务

                (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);

                //pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

            }

        }

        else//点对点发送邮件

        {

            (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);

            //pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

        }

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        if ((opt & OS_POST_OPT_NO_SCHED) == 0u)

        {

            OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

        }

        return (OS_ERR_NONE);//邮件发完,返回

  }

///没有发现消息邮箱挂起的任务” ///

if (pevent->OSEventPtr != (void *)0) //查询邮箱中的内容是否被接收

{//上次发送的邮件没有被接收

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_MBOX_FULL); //没有执行发送消息邮箱,就退出了

}

/上次发送的消息邮箱中的内容已经被读取/

pevent->OSEventPtr = pmsg;

//pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

//pmsg是指向消息邮箱的数据块地址

OS_EXIT_CRITICAL();

    return (OS_ERR_NONE); //执行发送消息邮箱后,才退出

}

4、OSMboxAccept (OS_EVENT *pevent)无等待接收邮件

函数功能:返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

// pevent为消息邮箱的指针

//返回指针就是消息邮箱的数据块首地址

void  *OSMboxAccept (OS_EVENT *pevent)

{

    void      *pmsg;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

{//pevent指针为0

        return ((void *)0);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

{//事件类型不是消息邮箱

    return ((void *)0);

}

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

    pmsg = pevent->OSEventPtr; //接收邮件,读取消息邮箱的数据块首地址

pevent->OSEventPtr = (void *)0;

//新邮箱数据接收到后,则立即清除消息邮箱的数据块指针,便于下次发送邮箱新数据

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

    return (pmsg); //返回邮箱数据块首地址 

}

5、*OSMboxPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr)

timeout=0任务会一直挂起,直到收到新邮件

timeout!=0任务在timeout个节拍内,若收到新邮件,则退出,否则,超时退出邮件接收

函数功能:*per= OS_ERR_NONE,且返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

// pevent为消息邮箱的指针

// timeout为等待时间;timeout=0任务会一直挂起,直到收到新邮件

//返回指针就是消息邮箱的数据块首地址

void  *OSMboxPend (OS_EVENT  *pevent,

                   INT32U     timeout,

                   INT8U     *perr)

{

void      *pmsg;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#ifdef OS_SAFETY_CRITICAL

if (perr == (INT8U *)0)

{// perr指针为0

        OS_SAFETY_CRITICAL_EXCEPTION();//这句看不懂,不要关心

    }

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

 {// pevent指针为0

        *perr = OS_ERR_PEVENT_NULL;

        return ((void *)0);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

{//事件类型不是消息邮箱

        *perr = OS_ERR_EVENT_TYPE;

        return ((void *)0);

}

if (OSIntNesting > 0u)

{//中断嵌套级别大于0

        *perr = OS_ERR_PEND_ISR;

        return ((void *)0);

}

if (OSLockNesting > 0u)

{//多任务锁定嵌套级别大于0

        *perr = OS_ERR_PEND_LOCKED;

        return ((void *)0);

}

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

pmsg = pevent->OSEventPtr; //接收邮件,读取消息邮箱的数据块首地址

if (pmsg != (void *)0)

{//”消息邮箱的数据块首地址不为0,表示消息邮箱的新数据被收到

        pevent->OSEventPtr = (void *)0;

//新邮箱数据接收到后,则立即清除消息邮箱的数据块指针,便于下次发送邮箱新数据

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        *perr = OS_ERR_NONE;

        return (pmsg); //返回邮箱数据块首地址

}

///没有收到消息邮箱的新数据”/

OSTCBCur->OSTCBStat     |= OS_STAT_MBOX;

    OSTCBCur->OSTCBStatPend=OS_STAT_PEND_OK; // 消息不可用,设置任务将进入等待

OSTCBCur->OSTCBDly       = timeout;//设置任务延迟的节拍数

    OS_EventTaskWait(pevent);// 暂停当前任务,直到发生事件或超时为止

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

    OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

   

//其他任务执行完后,回到当前任务//

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

switch (OSTCBCur->OSTCBStatPend)

{

    case OS_STAT_PEND_OK: //任务已经等到消息邮箱的新数据

             pmsg = OSTCBCur->OSTCBMsg;//读取邮箱数据块首地址

            *perr =  OS_ERR_NONE;

             break;

        case OS_STAT_PEND_ABORT://任务没有等到消息邮箱的新数据

             pmsg = (void *)0;

            *perr =  OS_ERR_PEND_ABORT;

             break;

        case OS_STAT_PEND_TO: //任务因没有等到消息邮箱的新数据导致超时

        default:

             OS_EventTaskRemove(OSTCBCur, pevent);

             pmsg = (void *)0;

            *perr =  OS_ERR_TIMEOUT;

             break;

}

OSTCBCur->OSTCBStat  =  OS_STAT_RDY;//设置当前任务状态为准备状态

OSTCBCur->OSTCBStatPend=OS_STAT_PEND_OK; // 消息不可用,设置任务将进入等待

OSTCBCur->OSTCBEventPtr= (OS_EVENT *)0;//清除消息邮箱的指针

#if (OS_EVENT_MULTI_EN > 0u)

    OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;

#endif

OSTCBCur->OSTCBMsg= (void *)0;

//新邮箱数据接收到后,则立即清除消息邮箱的数据块指针,便于下次发送邮箱新数据

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

return (pmsg); //返回邮箱数据块首地址                                   

}

//延时ticks节拍数

void  OSTimeDly (INT32U ticks)

{

    INT8U      y;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

if (OSIntNesting > 0u)

 {

        return;

}

if (OSLockNesting > 0u)

{

        return;

}

if (ticks > 0u)

{

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

        y  =  OSTCBCur->OSTCBY;

        OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;

        if (OSRdyTbl[y] == 0u)

{

            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;

        }

        OSTCBCur->OSTCBDly = ticks;//装载时钟节拍数

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/589290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文秒懂BI是什么?

在数字化时代背景下,商业智能(Business Intelligence,简称BI)成为了信息化热词,我们经常能听到企业说“上BI”、“建设BI系统”、“构建BI决策平台”“BI数据分析”“BI可视化”等内容。 一、那么BI到底是什么呢&…

如何在IEEE的模板中引用Arxiv中的论文

如何在IEEE的模板中引用Arxiv中的论文 本文章记录如何在IEEE Transactions的模板中,引用Arxiv中的论文,记录具体的论文格式信息。 目录 如何在IEEE的模板中引用Arxiv中的论文1.在IEEE的模板中引用Arxiv中的论文格式是怎么样的呢?2.在bib文件…

C# 事件(event)

目录 一、概述 二、事件和委托的区别 委托和事件的概念 委托和事件的作用 委托和事件的区别 三、事件的基本用法 结束 一、概述 事件是一种特殊的多播委托,仅可以从声明事件的类(或派生类)或结构(发布服务器类&#xff09…

Revit中门窗的翻转控件该如何添加?

一、门窗的翻转控件该如何添加? 放置过门窗的小伙伴会发现,门窗是可以进行左右前后进行翻转的,可以通过这些小按钮或是空格键进行门窗的朝向,十分的人性化,可以帮我们更好的放置门窗。一般上我们创建门窗族时系统会自动为我们添加…

我们和ChatGPT聊了聊BI的未来

ChatGPT是什么? ChatGPT是OpenAI开发的聊天机器人,2022年11月上线,迅速火爆全球,1周突破100万用户,仅用2个月全球突破1亿用户,碾压史上所有应用程序。美国有学生用ChatGPT写论文拿下全班最高分,ChatGPT可以…

微信支付链接二维码生成

1、进入composer官方网站,搜索phpqrcode安装包 composer命令安装 composer require aferrandini/phpqrcode 生成二维码图片的公共方法: // 公用二维码生成 static function setQrcode($url){//二维码图片保存路径$path advert/qrcode/.date("Ymd&q…

JavaScript高级二、构造函数常用函数

零、文章目录 JavaScript高级二、构造函数&常用函数 1、深入对象 &#xff08;1&#xff09;创建对象三种方式 利用对象字面量创建对象 利用 new Object 创建对象 利用构造函数创建对象 案例如下&#xff1a; <!DOCTYPE html> <html lang"en"&g…

干货分享:小红书商业化+微信社区运营,引流自动裂变拓客方案

干货分享&#xff1a;小红书商业化微信社区运营&#xff0c;引流自动裂变拓客方案 背景&#xff1a;2023为止小红书基本已是当代年轻人都会下载和使用的软件了&#xff0c;小红书是生活方式平台和消费决策入口&#xff0c;通过智能机器人学习和对用户的精准智能匹配走红&#x…

chatgpt赋能python:Python中datetime的用法

Python 中datetime的用法 介绍 在 Python 中&#xff0c;datetime 是一个非常重要和常用的模块&#xff0c;它提供了很多操作日期和时间的函数。datetime 模块中最主要的三个类是 datetime、date 和 time。其中 datetime 类是 date 和 time 的组合&#xff0c;所以这里只介绍…

C++读写文本文件

2023年5月30日&#xff0c;周二下午&#xff1a; 这几天学习了C对文本文件的读写&#xff0c;写篇博客来总结一下 由于内容太多&#xff0c;我没法一次性写完&#xff0c;之后会不定期更新的 我使用C标准库中的fstream库来读写文本文件 用fstream来读写文本文件有两种方式&a…

element dialog对话框中select/cascader 弹窗不跟随问题

Element 在使用对话框中出现的情况 Select 选择器 Cascader 级联选择器 在这两种组件组合使用是出现了滑动 弹出框不跟随情况&#xff0c;如下 出现这种情况原因是因为弹出框相对的位置是body&#xff0c;展示后&#xff0c;如果body不动&#xff0c;所以弹窗位置不会发生改变…

研发工程师玩转Kubernetes——创建一个测试容器

测试容器并不是什么都没有的容器&#xff0c;只是它没有我们期望的常驻进程。我们常用它来做一些测试。 举个例子&#xff0c;在《研发工程师玩转Kubernetes——自动扩缩容》中我们使用本地wrk进行了压力测试。如果我们希望进入容器手工调用wrk&#xff0c;该怎么做呢&#xff…

后摩尔时代,洞见第三代功率半导体器件参数测试的趋势和未来!

前言 2022年&#xff0c;全球半导体产业连续高增长&#xff0c;进入调整周期。与此形成对比&#xff0c;在新能源汽车、光伏、储能等需求带动下&#xff0c;第三代半导体产业保持高速发展&#xff0c;全球化供应链体系正在形成&#xff0c;竞争格局逐步确立&#xff0c;产业步…

网络协议格式 | 以太网帧、ARP数据报、IP数据报、UDP数据报、TCP数据报

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

计算机视觉实战--OpenCV进行红绿灯识别

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 OpenCV是一个开源的计算机视觉库&#xff0c;可以用于实现各种图像和视频处理任务&#xff0c;包括红绿灯识别。可以帮助自动驾驶汽车、智能交通系统等设备准确地识别红绿灯的状态&#xff0c;以便做出正确的决策。今天&a…

2022-Deep generative molecular design reshapes drug discovery-分子生成设计重塑药物发现

文章目录 药物发现中的深度生成模型化合物/分子的表示 Deep Generative Models递归神经网 RNN变分自动编码器 VAE生成性对抗网络 (Generative Adversarial Networks, GANs)Flow-based models强化学习(Reinforcement Learning, RL) 在小分子药物设计中的应用生成有效的小分子生成…

X2000 freeRTOS usb_bulk通信

例程 官方例程..\freertos\example\usb\device\gadget_generic_bulk.c&#xff0c;代码如下&#xff1a; #include <common.h> #include <usb/gadget_bulk.h> #include <os.h>static const struct gadget_id bulk_id {.vendor_id 0x1CBE,.product_id 0x…

3.1. 字符串与StringBuilder

1. 字符串&#xff08;String&#xff09; 在Java中&#xff0c;字符串由String类表示。字符串是一系列字符的组合&#xff0c;用于表示文本数据。字符串是不可变的&#xff0c;这意味着一旦创建了一个字符串对象&#xff0c;就不能修改它的内容。 创建字符串 创建字符串的方…

真的裂开了呀,现在的00后,真是卷死了,辞职信已经写好了

谁说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;上个月我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪22K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …

Android 应用打包和编译技术

Android 应用打包和编译技术非常重要&#xff0c;因为它们可以帮助开发者将代码转换成可执行的应用程序&#xff0c;并优化应用程序的性能和稳定性。 1. Gradle Gradle 是基于 Groovy 语言和 Java 虚拟机&#xff08;JVM&#xff09;运行的构建工具&#xff0c;通过它来配置应…