STM32cubeMX配置FreeRTOS----互斥量

这篇文章为大家介绍FreeRTOS里的 互斥锁

文章目录

  • 前言
  • 一、互斥量的概念
  • 二、STM32cubeMX配置互斥量
  • 三、相关函数
      • 1. 创建互斥量
      • 2. 获取互斥量
      • 3. 释放互斥量
  • 四、使用互斥量访问共享资源
  • 五、递归互斥锁
      • 在RTOS里互斥锁是谁获取,谁就释放吗?
  • 总结

前言


一、互斥量的概念

  • 问 :什么是互斥量?
  • 答 :互斥量其实就是互斥锁,用来保护临界(共享)资源的访问。

互斥量(Mutex)是一种同步机制,用来确保同一时刻只有一个线程或任务在访问共享资源。防止多个线程同时访问共享资源而造成的数据不一致性,保护临界资源的访问

使用场景:当有多个任务 或 线程同时访问共享资源。
在这里插入图片描述

二、STM32cubeMX配置互斥量

关于前面的基础配置可以参考我之前的文章:STM32cubeMX配置FreeRTOS工程

创建互斥锁:
在这里插入图片描述
在这里插入图片描述
Mutex Name:互斥量名字
Allocation:分配方式
Control Block Name:互斥量控制块名字

三、相关函数

1. 创建互斥量

	osMutexId_t osMutexNew(const osMutexAttr_t *attr);

返回值:
osMutexId_t :互斥量的标识符,用于后续对互斥量的操作。
参数:
attr :互斥量的属性,包括优先级、名称等。可以为 NULL ,表示使用默认属性。

2. 获取互斥量

	osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout);

返回值:
osStatus_t :表示互斥量获取的状态,可能的取值包括 osOK 、 osErrorResource (资源不可
用)、 osErrorTimeout (超时)等。
参数:
mutex_id :要获取的互斥量的标识符。
timeout :等待互斥量的最大时间,通常以毫秒为单位。可以为 osWaitForever 表示无限等待,
也可以是一个具体的时间值。

3. 释放互斥量

	osStatus_t osMutexRelease(osMutexId_t mutex_id);

返回值:
osStatus_t :表示互斥量释放的状态,通常为 osOK 。
参数:
mutex_id :要释放的互斥量的标识符。

四、使用互斥量访问共享资源

设置一个全局变量为共享资源,创建两个任务去访问全局变量,让变量增加。

// 共享资源-----全局变量
int share_data = 0;// 任务 2
void StartTask02(void *argument)
{/* USER CODE BEGIN StartTask02 *//* Infinite loop */for(;;){// 获取 互斥锁(上锁)osMutexAcquire(myMutex01Handle, osWaitForever);share_data++;printf("task2 share_data : %d\r\n", share_data);// 释放互斥锁(解锁)osMutexRelease(myMutex01Handle);osDelay(1000);}/* USER CODE END StartTask02 */
}// 任务 3 
void StartTask03(void *argument)
{/* USER CODE BEGIN StartTask03 *//* Infinite loop */for(;;){// 获取 互斥锁(上锁)osMutexAcquire(myMutex01Handle, osWaitForever);share_data++;printf("task3 share_data : %d\r\n", share_data);// 释放互斥锁(解锁)osMutexRelease(myMutex01Handle);		osDelay(1000);}/* USER CODE END StartTask03 */
}

五、递归互斥锁

在RTOS里互斥锁是谁获取,谁就释放吗?

回答 : 否。

互斥锁 / 互斥量的概念确实是 谁获取,谁就释放。但是在 FreeRTOS 里并不支持这个观点。

在 FreeRTOS 中,标准互斥锁可以由其他任务来释放。递归互斥锁实现了 谁上锁,就由谁解锁。

在 下面的例子中,创建了一个递归互斥锁。 任务 1 获取互斥量后会延迟一段时间,在这段时间内任务2 不会释放 任务1 的互斥量。

// 创建递归互斥锁
static SemaphoreHandle_t mutex1_handle;
mutex1_handle = xSemaphoreCreateRecursiveMutex();// 任务1 
void Task1Function(void * param)
{while (1){// 获取互斥量xSemaphoreTakeRecursive(mutex1_handle, portMAX_DELAY);printf("Task1 Take \r\n");printf("%s\r\n",(char*)param);vTaskDelay(5);// 释放互斥量xSemaphoreGiveRecursive(mutex1_handle);printf("Task1 Give \r\n");}
}// 任务2
void Task2Function(void * param)
{while (1){		if (xSemaphoreTakeRecursive(mutex1_handle, 0) != pdTRUE){if(xSemaphoreGiveRecursive(mutex1_handle))		printf("Task2 : xSemaphoreGive success\r\n");}else{printf("%s\r\n",(char*)param);xSemaphoreGiveRecursive(mutex1_handle);		// 释放互斥量}	}
}

在这里插入图片描述


总结

下一篇文章为大家介绍 信号量队列

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

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

相关文章

MySQL引擎对决:深入解析MyISAM和InnoDB的区别

欢迎来到我的博客,代码的世界里,每一行都是一个故事 MySQL引擎对决:深入解析MyISAM和InnoDB的区别 前言引擎概述MyISAM:InnoDB: 使用场景使用 MyISAM 的最佳实践:使用 InnoDB 的最佳实践:可能的…

使用Windbg动态调试目标程序去分析异常的两实战案例分享

目录 1、前言 2、案例1:程序退出时弹出报错提示框 2.1、问题说明 2.2、到系统应用程序日志中看系统有没有自动生成dump文件 2.3、将Windbg附加到目标程序上进行动态调试 3、案例2:程序在运行过程中弹出ASSERT断言提示框 3.1、问题说明 3.2、将Wi…

Linux内核中并发与竞争的处理方法之原子操作简介

一. 简介 当我们发现驱动程序中存在并发和竞争的时候一定要处理掉,接下来我们依次来学习一下 Linux 内核提供的几种并发和竞争的处理方法。 本文学习Linux内核提供的一种处理并发与竞争的方法:原子操作。 二. 原子操作简介 原子操作就是指不能再进一步…

net反射

1.1 查找dll文件 Load需要把dll放到程序当前路径加载,也可以读取字符串形式。LoadFrom需要写全路径,如果test1.dll引用了test2.dll,同时也会加载test2.dll进来。LoadFile不会加载test2.dll。 Assembly assembly1 Assembly.Load("DllTe…

Gmail邮箱群发邮件的技巧?邮箱怎么绑定?

Gmail邮箱注册教程指南?如何注册新的Gmail邮箱帐户? Gmail邮箱作为谷歌推出的邮件服务,以其高效、稳定和便捷的特性受到广大用户的喜爱。然而,如何在Gmail中进行有效的群发邮件,接下来,蜂邮将给大家介绍一…

盘点那些世界名校计算机专业采用的教材

清华、北大、MIT、CMU、斯坦福的学霸们在新学期里要学什么?今天我们来盘点一下那些世界名校计算机专业采用的教材。 书单目录 1.《深入理解计算机系统》(原书第3版)2. 《算法导论》(原书第3版)3. 《计算机程序的构造和…

酷开科技丨新年新玩法!酷开系统壁纸模式给客厅“换”新

甲辰龙年即将到来,新年新家新气象,快到酷开系统壁纸模式中挑选一款喜欢的壁纸,为新的一年增添一份美好和喜悦吧! 酷开科技将更多的电视新玩法带给你,让你的电视成为家庭中的焦点!酷开系统壁纸模式&#xf…

【Linux】再谈进程地址空间

目录 一、引入 二、物理内存和外设空间的交互 三、解决页表过大问题 一、引入 我们在往期的博客中有讲解过进程地址空间:【Linux】进程地址空间 但是在上述博客中我们只是对进程地址空间的左边部分详细进行了讲解,下面我们就来谈谈右边的部分&#…

【Effective Objective - C】—— 系统框架

【Effective Objective - C】—— 系统框架 47.熟悉系统框架CoreFoundation框架其他框架要点 48. 多用块枚举,少用for循环for循环使用Objective-C 1.0的NSEnumerator遍历快速遍历基于块的遍历方式要点 49.对自定义其内存管理语义的collection使用无缝桥接要点 50.构…

【数据结构】_队列

目录 1.概念 2.队列的使用 3.队列模拟实现 4.循环队列 5.双端队列 6.栈与队列的互相实现 6.1 用队列实现栈 6.2 用栈实现队列 1.概念 (1)队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表; &am…

Javascript中var和let之间的区别

文章目录 一.变量提升(声)二.let和var的区别 区别: 1、var有变量提升,而let没有; 2、let不允许在相同的作用域下重复声明,而var允许; 3、let没有暂时性死区问题; 4、let创建的全局变量没有给window设置对应…

uniapp微信小程序-项目实战修改密码

图标是使用uview里面的图标&#xff0c;icfont也可以 以下是所有代码 <template><view><!-- 密码三个 --><view class"password" v-for"(item,index) in userList"><view class"contentuser"><view class&qu…