【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);
    }

    // 初始化成功,返回0
    return 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);

    // 锁获取成功,返回0
    return 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);

    // 锁释放成功,返回0
    return 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))); 
    } 

    // 初始化成功,返回0
    return 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); 
    
    // 成功获取锁后返回0
    return 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); 

    // 释放锁成功,返回0
    return 0; 
}
5.4.2 参数/函数讲解
序号函数说明
1osMutexRelease释放互斥锁,允许其他任务使用

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

请添加图片描述


总结

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

在这里插入图片描述

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

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

更多专栏订阅:

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

  • 🥇 【恒玄BES】

  • 🌼 【鸿蒙系统】

  • 💎 【蓝牙协议栈】

  • 🎃 【死机分析】

  • 👑 【Python脚本笔记】

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

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

  • 【JavaScript随手笔记】

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

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

  • 🔐 【Git 学习笔记】

  • 🚀 【软件安装教程】



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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《mysql》--mysql约束

数据库约束 有的时候数据库中的数据是有一定要求的&#xff0c;有些数据认为是合法数据&#xff0c;有些是非法数据&#xff0c;如果靠人工检查显然是不靠谱的&#xff1b; 数据库会自动的对数据的合法性进行校验检查目的就是&#xff0c;保证数据中能够避免被插入/修改一些非…

工业AIoT竞赛流程

不要点到重置&#xff01;&#xff01;&#xff01;要刷新虚拟机就点重启 xshell连接虚拟机&#xff1a;ssh rootPublic IP 环境构建 vim /etc/hosts 按 i 进入插入模式&#xff0c;加内网ip和主机名&#xff0c;按esc&#xff0c;按 : &#xff0c;按wq 三个虚拟机都这样配 …

RabbitMQ实践——定制一致性Hash交换器的路由字段

大纲 Property法定制交换器绑定队列测试 Header法定制交换器绑定队列测试 代码工程参考资料 在《RabbitMQ实践——利用一致性Hash交换器做负载均衡》一文中&#xff0c;我们熟悉了一致性Hash交换器的使用方法。默认的&#xff0c;它使用Routing key来做Hash的判断源。但是有些时…

查看呗占用端口,并且删除该端口

点击windows开始菜单输入cmd 或者使用“winr”键来打开窗口 窗口中输入netstat -ano|findstr 18088 查找18088端口的进程 根据pid删除进程taskkill /pid 18088 -t -f

第4章 客户端-Java客户端Jedis

1.获取Jedis maven配置加入项目中 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.2</version> </dependency>2.Jedis的基本使用 Jedis的使用方法非常简单&#xff0c;只要下面三…

理解IP地址与域名:访问网站的基石

在互联网的世界里&#xff0c;每一次点击、每一次浏览都伴随着一个神秘的数字串——IP地址&#xff0c;以及一个易于记忆的字符串——域名。对于普通用户而言&#xff0c;这两者可能只是浏览网页时的“幕后英雄”&#xff0c;但实际上&#xff0c;它们构成了我们访问网站的基石…

【EtherCAT】TwinCAT3通过PLC修改SDO数据

目录 1、打开twincat3, 左边PLC右键->添加新项&#xff0c;建立PLC工程 2、->References右键添加库 3、找到Tc2_EtherCAT库&#xff0c;点确定。 4、PLC程序ST语言就可以调用下面的功能块函数 5、PLC编程界面右键->输入助手 1、打开twincat3, 左边PLC右键->添…

element ui form 表单验证

表单验证方法 在el-form元素上总体设置校验规则rules&#xff0c;下面是官方案例 <el-form :model"ruleForm" :rules"rules" ref"ruleForm" label-width"100px" class"demo-ruleForm"><el-form-item label"…

单目标应用:基于吸血水蛭优化器(Blood-Sucking Leech Optimizer,BSLO)的微电网优化(MATLAB代码)

一、微电网模型介绍 微电网多目标优化调度模型简介_vmgpqv-CSDN博客 参考文献&#xff1a; [1]李兴莘,张靖,何宇,等.基于改进粒子群算法的微电网多目标优化调度[J].电力科学与工程, 2021, 37(3):7 二、吸血水蛭优化器求解微电网 2.1算法简介 吸血水蛭优化器&#xff08;B…

科技助力行政执法:4G无线网络技术在管理指挥中心的应用

随着科技的飞速发展&#xff0c;4G无线网络技术已经越来越成熟&#xff0c;为行政执法管理带来了前所未有的便利与效率。特别是在管理指挥中心&#xff0c;通过实时观看高清现场画面&#xff0c;执法人员可以随时进行调度指挥&#xff0c;掌握行政执法队伍的全过程&#xff0c;…

2024年03月Python六级真题+答案(中国电子学会 )

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;六级&#xff09; 分数&#xff1a;100 题数&#xff1a;38 一、单选题(共25题&#xff0c;共50分) 1.以下选项中&#xff0c;创建类正确的是&#xff1f;&#xff08; &#xff09; A. class test1…

Java——枚举

1. 概念 枚举是在JDK1.5之后引入的&#xff0c;主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式&#xff1a; public static final int RED 1; public static final int GREEN 2; public static final int BLACK 3;但是…

ED系列可读可写低频地埋电子标识器(内置SIC279芯片)数据写入说明

ED系列低频地埋电子标识器&#xff08;内置SIC279芯片&#xff09;&#xff0c;即带ID可读可写电子标识器&#xff0c;包含ED1100-ID-RW&#xff0c;ED1500-ID-RW&#xff0c;ED2000-ID-RW&#xff0c;支持按固定格式写数据的地埋电子标识器。 ED系列可读可写低频地埋电子标识…

大猫咪守护LoRA:定制你的大猫私人大猫咪宠物写真合影,某音某书流行款

&#x1f339;大家好&#xff01;我是安琪&#xff01;感谢大家的支持与鼓励。 大猫咪LoRA模型简介 今天应群里同学大猫咪宠物合影写真提议&#xff0c;为大家介绍一款来自作者 沐沐人像合成的主题为大猫咪守护的LoRAl模型&#xff1a;沐沐-大猫咪。这是一款当下在某音、某书…

【5G核心网】5G NWDAF(Network Data Analytics Function)网元功能介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

sql查询CONCAT、group_concat、concat_ws函数用法

SELECT str_code, 1 CONCAT 连接多字段字符串就模糊查询 select CONCAT(dept_name, , dept_code , , parent_id) ,* from sys_dept where CONCAT(dept_name, , dept_code , , parent_id) LIKE %16% 2、语法&#xff1a;group_concat( [distinct] 要连接的字段 [order by …

光模块市场受益于AI热潮同比增长45%,行业前景看好

近日&#xff0c;市场研究机构YOLE Group在最新的市场报告中指出&#xff0c;AI驱动的光模块市场将出现同比45%的增长。预计至2024年&#xff0c;数据通信领域的人工智能光收发器市场将实现高达45%的同比增长&#xff0c;展现出了强大的市场活力和广阔的发展前景。 光收发器市…

Amazon OpenSearch Service 现在支持 JSON Web Token(JWT)身份验证和授权

最近&#xff0c;Amazon OpenSearch 推出了一个新功能&#xff0c;支持 JWT 认证和授权。虽然这个功能在开源的 OpenSearch 中早已存在&#xff0c;但在托管的 Amazon OpenSearch 中的实现一直不够理想。 此前的授权方式 控制台登录 内部数据库&#xff1a;使用基本的用户名…

【分布式系列】分布式锁在 Redis 主从部署中的挑战

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

易基因:围产期母体有毒物质暴露对子代血液、大脑和肝脏DNA甲基化的影响 | 研究速递

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 母体在环境化学物质中暴露可能对后代的健康造成不利影响。越来越多的证据支持这些不良效应至少部分受表观遗传修饰调控。目前尚不清楚血液中的表观遗传变化是否反映了大脑皮层或肝脏等目…