μC/OS-II---互斥信号量管理2(os_mutex.c)

目录

  • 背景:优先级反转问题
  • 互斥信号量管理
    • 互斥信号量发出(释放)
    • 互斥信号量获取/无等待
    • 互斥信号量状态查询

在这里插入图片描述

背景:优先级反转问题

  • 在高优先级任务等待低优先级任务释放资源时,第三个中等优先级任务抢占了低优先级任务。阻塞时间是无法预测的,可能导致高优先级任务无法满足deadline。这是需要解决的问题。μC/OS-II采用的办法:优先级继承协议。【实际采用的方法是由互斥信号量先预占一个优先级】

互斥信号量管理

互斥信号量发出(释放)

INT8U  OSMutexPost (OS_EVENT *pevent)
{INT8U      pcp;                                   /* Priority ceiling priority                     */INT8U      prio;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */OS_CPU_SR  cpu_sr = 0u;
#endifif (OSIntNesting > 0u)                            /* See if called from ISR ...                    */{return (OS_ERR_POST_ISR);                     /* ... can't POST mutex from an ISR              */}#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                      /* Validate 'pevent'                             */{return (OS_ERR_PEVENT_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MUTEX)   /* Validate event block type                     */{return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();pcp  = (INT8U) (pevent->OSEventCnt >> 8u);        /* Get priority ceiling priority of mutex        */prio = (INT8U) (pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority      */if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr)     /* See if posting task owns the MUTEX            */{OS_EXIT_CRITICAL();return (OS_ERR_NOT_MUTEX_OWNER);}if (pcp != OS_PRIO_MUTEX_CEIL_DIS){if (OSTCBCur->OSTCBPrio == pcp)               /* Did we have to raise current task's priority? */{OSMutex_RdyAtPrio (OSTCBCur, prio);       /* Restore the task's original priority          */}OSTCBPrioTbl[pcp] = OS_TCB_RESERVED;          /* Reserve table entry                           */}if (pevent->OSEventGrp != 0u)                     /* Any task waiting for the mutex?               */{/* Yes, Make HPT waiting for mutex ready         */prio                = OS_EventTaskRdy (pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;  /*      Save priority of mutex's new owner       */pevent->OSEventCnt |= prio;pevent->OSEventPtr  = OSTCBPrioTbl[prio];     /*      Link to new mutex owner's OS_TCB         */if ((pcp  != OS_PRIO_MUTEX_CEIL_DIS) &&(prio <= pcp))                            /*      PCP 'must' have a SMALLER prio ...       */{OS_EXIT_CRITICAL();                       /*      ... than current task!                   */OS_Sched();                               /*      Find highest priority task ready to run  */return (OS_ERR_PCP_LOWER);}else{OS_EXIT_CRITICAL();OS_Sched();                               /*      Find highest priority task ready to run  */return (OS_ERR_NONE);}}pevent->OSEventCnt |= OS_MUTEX_AVAILABLE;         /* No,  Mutex is now available                   */pevent->OSEventPtr  = (void *)0;OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}

互斥信号量获取/无等待

#if OS_MUTEX_ACCEPT_EN > 0u
BOOLEAN  OSMutexAccept (OS_EVENT  *pevent,INT8U     *perr)
{INT8U      pcp;                                    /* Priority Ceiling Priority (PCP)              */
#if OS_CRITICAL_METHOD == 3u                           /* Allocate storage for CPU status register     */OS_CPU_SR  cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return (OS_FALSE);}#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                       /* Validate 'pevent'                            */{*perr = OS_ERR_PEVENT_NULL;return (OS_FALSE);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MUTEX)    /* Validate event block type                    */{*perr = OS_ERR_EVENT_TYPE;return (OS_FALSE);}if (OSIntNesting > 0u)                             /* Make sure it's not called from an ISR        */{*perr = OS_ERR_PEND_ISR;return (OS_FALSE);}OS_ENTER_CRITICAL();                               /* Get value (0 or 1) of Mutex                  */pcp = (INT8U) (pevent->OSEventCnt >> 8u);          /* Get PCP from mutex                           */if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE){pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;   /*      Mask off LSByte (Acquire Mutex)         */pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;     /*      Save current task priority in LSByte    */pevent->OSEventPtr  = (void *)OSTCBCur;        /*      Link TCB of task owning Mutex           */if ((pcp != OS_PRIO_MUTEX_CEIL_DIS) &&(OSTCBCur->OSTCBPrio <= pcp))              /*      PCP 'must' have a SMALLER prio ...      */{OS_EXIT_CRITICAL();                       /*      ... than current task!                  */*perr = OS_ERR_PCP_LOWER;}else{OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;}return (OS_TRUE);}OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;return (OS_FALSE);
}
#endif

互斥信号量状态查询

#if OS_MUTEX_QUERY_EN > 0u
INT8U  OSMutexQuery (OS_EVENT       *pevent,OS_MUTEX_DATA  *p_mutex_data)
{INT8U       i;OS_PRIO    *psrc;OS_PRIO    *pdest;
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */OS_CPU_SR   cpu_sr = 0u;
#endifif (OSIntNesting > 0u)                                 /* See if called from ISR ...               */{return (OS_ERR_QUERY_ISR);                         /* ... can't QUERY mutex from an ISR        */}#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                           /* Validate 'pevent'                        */{return (OS_ERR_PEVENT_NULL);}if (p_mutex_data == (OS_MUTEX_DATA *)0)                /* Validate 'p_mutex_data'                  */{return (OS_ERR_PDATA_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MUTEX)        /* Validate event block type                */{return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();p_mutex_data->OSMutexPCP  = (INT8U) (pevent->OSEventCnt >> 8u);p_mutex_data->OSOwnerPrio = (INT8U) (pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);if (p_mutex_data->OSOwnerPrio == 0xFFu){p_mutex_data->OSValue = OS_TRUE;}else{p_mutex_data->OSValue = OS_FALSE;}p_mutex_data->OSEventGrp  = pevent->OSEventGrp;        /* Copy wait list                           */psrc                      = &pevent->OSEventTbl[0];pdest                     = &p_mutex_data->OSEventTbl[0];for (i = 0u; i < OS_EVENT_TBL_SIZE; i++){*pdest++ = *psrc++;}OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}
#endif

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【postgresql】查看数据中表的信息

切换到postgresql数据库&#xff0c;各种不适应吧。 有个需求需要查询数据表的各种信息。 下面我们一起学习吧。 ●PostgreSQL: Documentation PostgreSQL: Documentation ●pg_namespace 存储名字空间。名字空间是 SQL 模式下层的结构&#xff1a;每个名字空间有独立的关系…

FPGA时序约束与分析-简单入门

FPGA时序约束与分析-简单入门 文章目录 FPGA时序约束与分析-简单入门1. 本课程概述2. 时序约束简介2.1 什么是时序约束2.2 合理的时序约束2.3 *基于Vivado的时序约束方法 3. 时序分析的基本概念3.1 时钟与时钟偏差3.2 建立时间和保持时间3.3 时序分析中路径、沿和关系的定义 4.…

V10chrony服务配置

Chrony简介 Chrony是一个开源自由的网络时间协议 NTP 的客户端和服务器软软件。它能让计算机保持系统时钟与时钟服务器&#xff08;NTP&#xff09;同步&#xff0c;因此让你的计算机保持精确的时间&#xff0c;Chrony也可以作为服务端软件为其他计算机提供时间同步服务。 Ch…

字符流的讲解 以及 Reader和Writer的用法

文章目录 ❤专栏导读❤字符流❤Reader类的操作 ❤Writer类操作❤Writer类的构造方法 ❤专栏导读 &#x1f680;《多线程》 &#x1f680;《数据结构剖析》 &#x1f680;《JavaSE语法》 在Java标准库中&#xff0c;提供的读写文件的流对象有很多很多的类&#xff0c;但是可以将…

计算机网络之物理层

物理层 1. 物理层的基本概念 2.物理层下面的传输媒体 传输媒体可分为两类&#xff0c;一类是导引型传输媒体&#xff0c;另一类是非导引型传输媒体。 3.传输方式 3.1 串行传输和并行传输 串行传输&#xff1a;串行传输是指数据是一个比特依次发送的&#xff0c;因此在发送端…

家居行业中跨区域EDI应用的优化策略

提到家居行业的国际知名企业&#xff0c;你会想到哪些&#xff1f;宜家IKEA还是家得宝The Home Depot&#xff1f;这些稳居家居行业第一梯队的企业都有哪些共同之处&#xff1f; 无论是北美市场还是欧洲市场&#xff0c;这些企业都有一个共同点&#xff1a;他们采用EDI&#x…

【Redis系列】Redis上设置key,value的时候出现NOAUTH Authentication required提示如何解决?

哈喽&#xff0c;大家好&#xff0c;我是小浪。相信大家在初学一门新的知识点的时候都会遇到各种各样的问题&#xff0c;在网上找了一大堆的解决方案&#xff0c;最后还是无功而返&#xff0c;那么今天博主就记录一下在进行Redis的一些操作中遇到的问题~ 当我们好不容易安装好R…

国际阿里云:提高CDN缓存命中率教程!!!

CDN缓存命中率低会导致源站压力大&#xff0c;静态资源访问效率低。您可以根据导致CDN缓存命中率低的具体原因&#xff0c;选择对应的优化策略来提高CDN的缓存命中率。 背景信息 CDN通过将静态资源缓存在CDN节点上实现资源访问加速。当客户端访问某资源时&#xff0c;如果CDN节…

给在读博士的建议

早上起床第一件事&#xff0c;瞄了眼知乎&#xff01; 发现现在的手机真的很智能&#xff0c;也许是聊天的时候不经意间提了一句&#xff0c;早上就推荐了自己想看到的东西&#xff01; 分享给大家&#xff01; 有哪些给在读博士的建议&#xff1f; 如何通过一句话判断一个博士…

LeetCode(12)时间插入、删除和获取随机元素【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 380. O(1) 时间插入、删除和获取随机元素 1.题目 实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回…

Karmada更高效地实现故障转移

随着云原生技术的发展&#xff0c;其应用场景不断扩大。越来越多的企业开始将应用程序部署在 Kubernetes 集群中&#xff0c;随着 Kubernetes 集群规模的不断扩大&#xff0c;也带来了许多管理挑战&#xff0c;例如多集群间负载均衡、资源调度、故障转移等问题。为了解决这些问…

【QT系列教程】之二创建项目和helloworld案例

文章目录 一、QT创建项目1.1、创建项目1.2、选择创建项目属性1.3、选择路径和项目名称1.4、选择构建项目类型1.5、布局方式1.6、翻译文件&#xff0c;根据自己需求选择1.7、选择套件1.8、项目管理&#xff0c;自行配置1.9、配置完成&#xff0c;系统自动更新配置 二、QT界面介绍…

istio学习笔记-安装

Istioldie 1.18 / 安装指南 基于Kubernetes的Istio的微服务架构需要安装以下组件&#xff1a; Istio控制平面组件&#xff1a;包括Istio-Pilot、Istio-Policy、Istio-Telemetry等。这些组件负责微服务的管理和配置&#xff0c;如流量管理、策略执行、遥测数据收集等。数据平面…

2023-11-15 LeetCode每日一题(K 个元素的最大和)

2023-11-15每日一题 一、题目编号 2656. K 个元素的最大和二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。你需要执行以下操作 恰好 k 次&#xff0c;最大化你的得分&#xff1a; 从 nums 中选择一个元素 m 。将选中…

安装 Lua 的 HTTP 库

首先&#xff0c;你需要安装 Lua 的 HTTP 库。可以使用 LuaRocks 来安装。以下是安装命令&#xff1a; luarocks install http然后&#xff0c;你可以使用以下代码来爬取网页内容&#xff1a; local http require http-- 设置代理信息 http.set_proxy(jshk.com.cn)-- 网页UR…

【C#学习】button:只显示图片

第一步&#xff1a;设置按钮背景图片&#xff0c;并且图片随按钮大小变化 第二步&#xff1a;设置按钮使之只显示图片 button1.FlatStyle FlatStyle.Flat;//stylebutton1.ForeColor Color.Transparent;//前景button1.BackColor Color.Transparent;//去背景button1.FlatAppe…

Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例

Flutter笔记 使用Flutter构建响应式PC客户端/Web页面-案例 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/detai…

Live800:客服行业的发展历程及未来前景

随着信息技术和互联网的高速发展&#xff0c;客服行业也在不断变革和发展。客服行业是一个服务型的行业&#xff0c;其发展历程也与人们对服务需求的变化密切相关。本文将介绍客服行业的发展历程和未来前景。 客服行业的发展历程 20世纪70年代&#xff0c;客服行业主要以电话服…

uniapp运行到安卓模拟器一直在“同步手机端程序文件完成“界面解决办法

如果你是用的模拟器是android studio创建的模拟器&#xff0c;那么你需要新创建一个android11 x86架构的模拟器&#xff1a; 创建完成后&#xff0c;启动模拟器&#xff1a; 然后在hbuilder中重新运行到这个模拟器就可以了&#xff1a; 运行结果&#xff1a; 如果你是用安…

算法:穷举,暴搜,深搜,回溯,剪枝

文章目录 算法基本思路例题全排列子集全排列II电话号码和字母组合括号生成组合目标和组合总和优美的排列N皇后有效的数独解数独单词搜索黄金矿工不同路径III 总结 算法基本思路 穷举–枚举 画出决策树设计代码 在设计代码的过程中&#xff0c;重点要关心到全局变量&#xff…