【BES2500x系列 -- RTX5操作系统】深入探索CMSIS-RTOS RTX -- 同步与通信篇 -- 信号量和互斥锁 --(三)

请添加图片描述

  • 💌 所属专栏:【BES2500x系列】

  • 😀 作  者:我是夜阑的狗🐶

  • 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!

  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩

请添加图片描述

文章目录

  • 前言
  • 1 介绍
  • 2 功能特性
  • 3 同步与通信
      • 3.1 同步(Synchronization)
      • 3.2 设计原则
      • 3.3 实例应用
  • 4 信号量
      • 4.1 定义信号量
        • 4.1.1 代码
        • 4.1.2 参数/函数讲解
      • 4.2 创建信号量
        • 4.2.1 代码
        • 4.2.2 参数/函数讲解
      • 4.3 获取信号量
        • 4.3.1 代码
        • 4.3.2 参数/函数讲解
      • 4.4 释放信号量
        • 4.4.1 代码
        • 4.4.2 参数/函数讲解
  • 5 互斥锁
      • 5.1 定义
        • 5.1.1 代码
        • 5.1.2 参数/函数讲解
      • 5.2 创建
        • 5.2.1 代码
        • 5.2.2 参数/函数讲解
      • 5.3 加锁
        • 5.3.1 代码
        • 5.3.2 参数/函数讲解
      • 5.4 解锁
        • 5.4.1 代码
        • 5.4.2 参数/函数讲解
  • 总结


前言

  大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第21篇文章;
  今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。
  专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。
  如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。


<<【系列文章索引】>>

1 介绍

  前面已经学习了 RTX 系统中线程管理的创建和使用,当然在操作系统中除了线程管理外,线程之间的同步与通信也是至关重要的,话不多说,那接下来就同步与通信都有那些内容吧,让我们原文再续,书接上回吧。

在这里插入图片描述

2 功能特性

  在实时操作系统(RTOS)中,任务管理和同步通信是关键组件,它们确保系统的高效和有序执行。本文将探讨这些概念,特别是线程管理、信号量、互斥锁、消息队列和邮箱处理。

  • 任务管理:RTX提供任务创建、调度和优先级管理,确保任务按照优先级及时执行。
  • 同步与通信:包括信号量、互斥锁、消息队列和邮箱,促进任务间的同步和数据交换。
  • 内存管理:内存池和动态内存分配,有效管理有限的系统资源。
  • 定时器服务:虚拟和硬件定时器,支持周期性任务和一次性事件触发。
  • 中断处理:保证中断服务的快速响应,同时保持任务的上下文安全。
  • 线程安全:通过内核级保护机制,防止多线程环境下的数据竞争和死锁。

3 同步与通信

  在实时操作系统(RTOS)中,同步与通信是确保任务间协调执行和数据交换的关键机制。以下是关于实时操作系统中同步与通信的几个核心概念和方法:

3.1 同步(Synchronization)

  • 目的:确保多个任务或中断处理程序在访问共享资源时的有序性和一致性,防止数据竞争和不一致。

  • 方法

    • 互斥锁(Mutex):用于保护临界区,确保同一时间只有一个任务可以访问共享资源。
    • 信号量(Semaphore):不仅可以实现互斥访问,还可以用于计数资源的可用性,支持多任务等待同一资源。
    • 事件标志(Event Flags):用于任务间的简单状态通信,一个任务可以设置某些事件标志,另一个任务可以等待这些标志被设置。
    • 消息队列(Message Queue):允许任务间传递数据结构或消息,同时也可以用作同步机制,发送者和接收者通过队列进行异步通信。

3.2 设计原则

  • 最小化阻塞:选择适当的同步和通信机制,减少任务等待时间,提高系统响应速度。
  • 确定性:确保所有同步和通信操作的时间复杂度是可预测的,以满足实时性要求。
  • 资源效率:考虑内存和CPU开销,选择最适合应用需求的机制。
  • 错误处理:实现健壮的错误处理逻辑,比如超时处理、死锁预防等。

3.3 实例应用

  在多传感器数据融合的场景中,可以使用消息队列来收集来自不同传感器的任务数据,并在主控制任务中进行融合处理。
  在电机控制应用中,通过互斥锁保护对电机控制寄存器的访问,避免并发写入导致的控制混乱。
  综上所述,实时操作系统中的同步与通信机制是实现可靠、高效、实时性应用的基础,正确地设计和应用这些机制对于保证系统性能和稳定性至关重要。

4 信号量

  我们接下来将详细介绍信号量和互斥锁。信号量是一种同步机制,用于控制对共享资源的访问。它可以是计数信号量或二进制信号量,用于管理多个线程的并发访问。

4.1 定义信号量

  信号量是一个计数器,用于控制对公共资源的访问。计数信号量可以有多个资源,二进制信号量只有两个状态:空闲(1)和占用(0)。
  一般在文件开头会看到这样的定义:osSemaphoreDef

4.1.1 代码
// 定义一个名为app_rtx_test_semaphore的互斥量
osSemaphoreDef(app_rtx_test_semaphore);// 定义一个变量app_rtx_test_semaphore_id,用于存储互斥量的ID
// 在实际操作中,这个ID将用于在运行时访问和操作互斥量
osSemaphoreId app_rtx_test_semaphore_id = NULL;
/*** 定义一个OS semaphore的结构体实例。* 这是一个宏,用于静态定义一个互斥量( semaphore),以便在操作系统中使用。* * @param name 互斥量的名称,用于标识和访问该互斥量。*/
#define osSemaphoreDef(name) \
static StaticSemaphore_t os_semaphore_cb_##name; /* 在静态内存中定义一个静态互斥量变量 */ \
const osSemaphoreDef_t os_semaphore_def_##name = \
{ NULL, 0U, (&os_semaphore_cb_##name), sizeof(StaticSemaphore_t) } /* 定义互斥量结构体,包含互斥量的控制块地址和其他必要信息 */
4.1.2 参数/函数讲解
序号函数说明
1osSemaphoreId定义变量来存储信号量的 ID
2osSemaphoreDef定义信号量结构体

4.2 创建信号量

  创建信号量通常通过调用 osSemaphoreCreate() 函数实现,传入定义好的信号量结构体和初始值。

4.2.1 代码
/*** 初始化名为app_rtx_test_semaphore的信号量。* 如果互斥量尚未创建,此函数将创建它并将其ID存储在全局变量app_rtx_test_semaphore_id中。** @return 总是返回0,表示初始化成功。*/
int app_rtx_test_sem_init(void) 
{// 检查互斥量ID是否为空if (app_rtx_test_semaphore_id == NULL) {// 创建互斥量,传入之前定义的信号量结构体和初始信号量值(这里是1)app_rtx_test_semaphore_id = osSemaphoreCreate(osSemaphore(app_rtx_test_semaphore), 1);}// 初始化成功,返回0return 0;
}
4.2.2 参数/函数讲解
序号函数说明
1osSemaphoreCreate创建信号量
2osSemaphore获取前面定义的信号量结构体

4.3 获取信号量

  线程通过 osSemaphoreWait() 函数请求信号量,如果资源可用,函数会立即返回;否则,线程会被挂起,直到资源可用。

4.3.1 代码
/*** 请求获取app_rtx_test_semaphore互斥量的锁。* 此函数会阻塞直到获得锁,或者在等待过程中被信号中断。** @return 总是返回0,表示锁获取成功。*/
int app_rtx_test_sem_lock(void) 
{// 等待获取互斥量锁,如果资源不可用,将一直等待osSemaphoreWait(app_rtx_test_semaphore_id, osWaitForever);// 锁获取成功,返回0return 0;
}
4.3.2 参数/函数讲解
序号函数说明
1osSemaphoreWait等待获取信号量

4.4 释放信号量

  当线程完成对资源的操作后,通过 osSemaphoreRelease() 函数释放信号量,让其他等待的线程有机会获取。

4.4.1 代码
/*** 释放app_rtx_test_semaphore互斥量的锁。* 此函数允许其他任务获取该互斥量。** @return 总是返回0,表示锁释放成功。*/
int app_rtx_test_sem_unlock(void) 
{// 释放信号量锁,允许其他任务使用osSemaphoreRelease(app_rtx_test_semaphore_id);// 锁释放成功,返回0return 0;
}
4.4.2 参数/函数讲解
序号函数说明
1osSemaphoreRelease释放信号量,允许其他任务使用

5 互斥锁

  互斥锁是另一种同步机制,确保同一时间只有一个线程访问特定资源。

5.1 定义

  一般在文件开头会看到这样的定义:osMutexDef

5.1.1 代码
// 声明一个互斥锁实例,使用osMutexDef宏并传入名称app_rtx_test_mutex
osMutexDef(app_rtx_test_mutex);// 定义一个osMutexId类型的变量,用于存储互斥锁的ID
// 在初始化后,该变量将持有app_rtx_test_mutex的标识符,以便在需要时进行锁定和解锁操作
osMutexId app_rtx_test_mutex_id = NULL;
/*** 定义一个互斥锁的宏。* * 该宏用于静态定义一个互斥锁(Mutex),支持递归和优先级继承特性。它通过提供一个名称来创建* 该互斥锁的相关静态数据结构。* * @param name 互斥锁的名称。该名称将用于为互斥锁的控制块和定义结构体命名。*/
#define osMutexDef(name) \
static StaticSemaphore_t os_mutex_cb_##name; /* 控制块静态存储区 */ \
const osMutexDef_t os_mutex_def_##name = \
{ NULL, osMutexRecursive | osMutexPrioInherit, (&os_mutex_cb_##name), sizeof(StaticSemaphore_t) } /* Mutex定义结构体 */
5.1.2 参数/函数讲解
序号函数说明
1osMutexId定义用于存储互斥锁的ID
2osMutexDef定义互斥锁结构体

5.2 创建

  创建互斥锁通常使用 osMutexCreate() 函数,传入互斥锁的定义。

5.2.1 代码
/*** 初始化指定的互斥锁。** 此函数负责初始化之前通过osMutexDef定义的app_rtx_test_mutex互斥锁。* 如果该互斥锁尚未被创建(即其ID为NULL),则会调用osMutexCreate进行创建。** @return 返回0表示初始化成功。由于此实现未处理失败情况,故假设初始化总是成功的。*/
int app_rtx_test_mutex_init(void) 
{// 检查互斥锁是否已初始化if (app_rtx_test_mutex_id == NULL) { // 使用osMutexDef定义的结构体创建互斥锁,并将其ID保存到app_rtx_test_mutex_id中app_rtx_test_mutex_id = osMutexCreate((osMutex(app_rtx_test_mutex))); } // 初始化成功,返回0return 0; 
}
5.2.2 参数/函数讲解
序号函数说明
1osMutexCreate创建互斥锁
2osMutex获取前面定义的互斥锁结构体

5.3 加锁

  线程使用 osMutexLock() 函数请求互斥锁,如果锁未被占用,线程会立即加锁;否则,线程会被挂起等待。

5.3.1 代码
/*** @brief          尝试获取互斥锁* * @description    该函数用于请求一个名为`app_rtx_test_mutex_id`的互斥锁。*                 使用`osWaitForever`参数表示函数将一直等待直到获得锁。*                 * @param[in]      无* * @return         返回值0表示成功获取了互斥锁。* * @note           若在多线程环境下其他线程已持有该锁,则调用此函数的线程会被挂起,*                 直到锁被释放。这可能导致当前线程阻塞,因此使用`osWaitForever`需谨慎。*/
int app_rtx_test_mutex_lock(void)
{// 调用osMutexWait来请求互斥锁,如果无法立即获取则无限等待osMutexWait(app_rtx_test_mutex_id, osWaitForever); // 成功获取锁后返回0return 0; 
}
5.3.2 参数/函数讲解
序号函数说明
1osMutexWait等待获取互斥锁

  这个函数 app_rtx_test_mutex_lock 用于获取一个已知的互斥锁 app_rtx_test_mutex 。它调用了实时操作系统(RTOS)的API osMutexWait ,传入互斥锁的句柄和一个标志 osWaitForever,表示如果锁不可用,当前任务将被挂起,直到能够获取锁为止。如果成功获取了锁,函数返回0。

5.4 解锁

  线程完成操作后,使用 osMutexUnlock() 函数释放互斥锁,允许其他线程获取。

5.4.1 代码
/*** 释放app_rtx_test_mutex互斥锁。** 当前任务持有互斥锁时,此函数将释放它,允许其他等待该锁的任务继续执行。** @return 返回0表示成功释放锁。由于此实现未处理失败情况,故假设锁总是能被成功释放。*/
int app_rtx_test_mutex_unlock(void) 
{// 调用RTX API释放互斥锁osMutexRelease(app_rtx_test_mutex_id); // 释放锁成功,返回0return 0; 
}
5.4.2 参数/函数讲解
序号函数说明
1osMutexRelease释放互斥锁,允许其他任务使用

<<【系列文章索引】>>

请添加图片描述


总结

  感谢观看,这里就是 boot loader 引导程序的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹

在这里插入图片描述

  也欢迎你,关注我。👍 👍 👍

  原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉

更多专栏订阅:

  • 😀 【LeetCode题解(持续更新中)】

  • 🥇 【恒玄BES】

  • 🌼 【鸿蒙系统】

  • 💎 【蓝牙协议栈】

  • 🎃 【死机分析】

  • 👑 【Python脚本笔记】

  • 🚝 【Java Web项目构建过程】

  • 💛 【微信小程序开发教程】

  • 【JavaScript随手笔记】

  • 🤩 【大数据学习笔记(华为云)】

  • 🦄 【程序错误解决方法(建议收藏)】

  • 🔐 【Git 学习笔记】

  • 🚀 【软件安装教程】



订阅更多,你们将会看到更多的优质内容!!

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

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

相关文章

帕金森患者吞咽困难?如何让饮食更顺畅!

在帕金森病患者的日常生活中&#xff0c;吞咽困难是一个常见而又棘手的问题。它不仅影响了患者的饮食质量&#xff0c;还可能导致营养不良、吸入性肺炎等严重并发症。那么&#xff0c;面对帕金森综合症导致的吞咽困难&#xff0c;我们该如何应对呢&#xff1f; 一、了解帕金森综…

一个去掉PDF背景水印的思路

起因 昨天测试 使用“https://github.com/VikParuchuri/marker” 将 pdf 转 Markdown的过程中&#xff0c;发现转换后的文件中会保护一些背景图片&#xff0c;是转换过程中&#xff0c;程序把背景图识别为了内容。于是想着怎么把背景图片去掉。 背景水印图片的特征 我这里拿…

openGuass数据库极简版安装和远程连接实战(阿里云服务器操作)

openGauss部署之后&#xff0c;在服务器上提供了在命令行下运行的数据库连接工具gsql。此工具除了具备操作数据库的基本功能&#xff0c;还提供了若干高级特性&#xff0c;便于用户使用。但图形化工具除了官方的Data Studio外&#xff0c;还可以使用SQLynx进行连接&#xff08;…

Taro + vue3 中微信小程序中实现拉起支付

在前端开发中 H5 的拉起支付和微信小程序的拉起支付 是不太一样的 现在分享一下微信小程序中的拉起支付 逻辑都在后端 我是用的Taro 框架 其实就是一个Api Taro 文档

酷开系统丨开启家庭智能教育让学习成为一种乐趣

在数字化时代&#xff0c;孩子们接触的信息日益增多&#xff0c;而酷开系统洞察到了家长对孩子成长环境的关切。酷开系统&#xff0c;作为家庭娱乐与教育的融合平台&#xff0c;不仅注重提供丰富的教育资源&#xff0c;更致力于创造一个健康、有益的学习和娱乐环境。 在酷开系…

【数据同步】什么是ETL增量抽取?

目录 一、什么是ETL增量抽取 二、企业如何应用ETL增量抽取 三、如何进行ETL增量抽取 1.基于时间戳的增量抽取 2.基于主键的增量抽取 在当今信息化时代&#xff0c;数据的快速增长和多样化使得企业面临着巨大的数据管理挑战。为了高效地处理和利用数据&#xff0c;ETL&#xff0…

零知识证明基础:对称加密与非对称加密

1、绪论 在密码学体系中&#xff0c;对称加密、非对称加密、单向散列函数、消息认证码、数字签名和伪随机数生成器被统称为密码学家的工具箱。其中&#xff0c;对称加密和非对称加密主要是用来保证机密性&#xff1b;单向散列函数用来保证消息的完整性&#xff1b;消息认证码的…

权限 chmod

参考&#xff1a; Linux chmod 命令 | 菜鸟教程 (runoob.com) Linux chmod&#xff08;英文全拼&#xff1a;change mode&#xff09;命令是控制用户对文件的权限的命令 Linux/Unix 的文件调用权限分为三级 : 文件所有者&#xff08;Owner Users&#xff09;用户组&#xff08…

Arduino - MG996R

Arduino - MG996R In this tutorial, we are going to learn how to use the MG996R high-torque servo motor with Arduino. 在本教程中&#xff0c;我们将学习如何将MG996R高扭矩伺服电机与Arduino一起使用。 Hardware Required 所需硬件 1Arduino UNO or Genuino UNO Ard…

windows系统如何快速查看显卡详情信息

winR&#xff0c;输入dxdiag 打开DirectX诊断工具&#xff0c;可以看到显卡的详细硬件信息

Vue原生写全选反选框

效果 场景&#xff1a;Vue全选框在头部&#xff0c;子框在v-for循环内部。 实现&#xff1a;点击全选框&#xff0c;所有子项选中&#xff0c;再次点击取消&#xff1b;子项全选中&#xff0c;全选框自动勾选&#xff0c;子项并未全选&#xff0c;全选框不勾选&#xff1b;已选…

国产音频放大器工作原理以及应用领域

音频放大器是在产生声音的输出元件上重建输入的音频信号的设备&#xff0c;其重建的信号音量和功率级都要理想&#xff1a;如实、有效且失真低。音频范围为约20Hz&#xff5e;20000Hz&#xff0c;因此放大器在此范围内必须有良好的频率响应&#xff08;驱动频带受限的扬声器时要…

无人机操作注意事项

检查飞行设备 每次飞行前&#xff0c;要认真检查无人机的各处细节&#xff0c;遥控器等地面设备也不例外。 确保设备电量充足 起飞前&#xff0c;检查无人机是否电量充足&#xff0c;以及辅助设备如遥控器、手机等。 选择空旷的飞行场地 选择适宜的场地进行操作&#xff0…

机器学习原理和代码实现专辑

1. 往期文章推荐 1.【机器学习】图神经网络(NRI)模型原理和运动轨迹预测代码实现 2. 【机器学习】基于Gumbel-Sinkhorn网络的“潜在排列问题”求解 3. 【机器学习】基于Gumbel Top-k松弛技术的图形采样 4. 【机器学习】基于Softmax松弛技术的离散数据采样 5. 【机器学习】正则…

GNU、Unix、Linux、Makefile、GCC、GDB、GPL、CentOS 7、Ubuntu之间的关系

全文总结 早期&#xff0c;Unix系统作为一类强大的操作系统&#xff0c;在计算领域奠定了基础。然而&#xff0c;出于对软件自由的追求&#xff0c;Richard Stallman在1983年发起了GNU项目&#xff0c;旨在创建一个完全自由的、与Unix兼容的操作系统。GNU项目不仅倡议软件自由…

空间转录组学联合单细胞转录组学揭示卵巢癌生存相关受配体对

卵巢癌&#xff0c;作为女性生殖系统中的一种常见恶性肿瘤&#xff0c;其高级别浆液性卵巢癌&#xff08;HGSC&#xff09;亚型尤其致命。尽管多数患者对初次治疗反应良好&#xff0c;但超过75%的晚期HGSC患者会在治疗后复发&#xff0c;并且对化疗药物产生耐药性。然而&#x…

vs code + Keil Assistant 配置 Keil 单片机开发

1、 先安装vscode完成后 安装插件 2 安装C/C 与 keil Assistant 需说明一下 Assistant 1.7.0版本有bug F7按不了 所以安装1.6.2版本 以下是我的安装插件 EMBEDDED IDE 可安装 可不安装 随便你 3 配置 Assistant 4、设置C/C 目录 ${workspaceFolder}/**D:/Keil_v5/C51/INC/**…

排序算法系列一:选择排序、插入排序 与 希尔排序

零、说在前面 本文是一个系列&#xff0c;入口请移步这里 一、理论部分 1.1&#xff1a;选择排序 1.1.1&#xff1a;算法解读&#xff1a; 使用二分法和插入排序两种算法的思想来实现。流程分为“拆分”、“合并”两大部分&#xff0c;前者就是普通的二分思想&#xff0c;将…

应急响应靶机-Linux(2)

前言 本次应急响应靶机采用的是知攻善防实验室的Linux-2应急响应靶机 靶机下载地址为&#xff1a; https://pan.quark.cn/s/4b6dffd0c51a 相关账户密码&#xff1a; root/Inch957821.(记住要带最后的点.) 解题 启动靶机 不建议直接使用账号密码登录&#xff0c;建议用另一台主…

900kW直流负载组-DC系列负载组

R900 DC 型是一个固定式 900kW 直流负载组&#xff0c;旨在准确模拟典型直流电源在实际运行过程中遇到的负载;例如用于物料搬运设备、固定电源和电动汽车领域的设备&#xff0c;例如车队车辆、地面支持设备 &#xff08;GSE&#xff09;、工业机器人等。 技术细节 负载组 R9…