STM32cubeMX配置FreeRTOS----互斥量

本文详细介绍了FreeRTOS中的互斥锁概念、在STM32cubeMX中的配置方法以及相关函数的使用。重点讨论了如何通过互斥锁保护共享资源访问,并区分了标准互斥锁与递归互斥锁的区别。后续将探讨信号量和队列的相关内容。

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

前言


一、互斥量的概念

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

互斥量(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);		// 释放互斥量
		}	
	}
}

在这里插入图片描述


总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖果罐子♡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值