STM32 HAL freertos零基础(七)互斥量

1、互斥量

互斥量主要用于保护共享资源的访问,确保在同一时刻只有一个任务可以访问该资源。

互斥性:当一个任务获取了一个互斥量后,其他任务将无法再获取同一个互斥量,直到原始任务释放该互斥量。
优先级继承:为了防止优先级反转问题,FreeRTOS的互斥量支持优先级继承机制。当一个高优先级任务被低优先级任务阻塞时,低优先级任务会暂时提升自己的优先级,以尽快释放互斥量,让高优先级任务继续执行。
递归锁定:互斥量支持递归锁定,即获取互斥量的任务可以在未释放的情况下再次获取同一个互斥量,直到所有获取操作都被相应次数的释放操作所抵消。

操作需求:建立三个不同优先级的任务,演示一下优先级翻转,接着通过互斥量进行解决。

2、相关API函数

注意:互斥信号量不能用于中断服务函数。

xSemaphoreCreateMutex() //使用动态方法创建互斥信号量。
xSemaphoreCreateMutexStatic() //使用静态方法创建互斥信号量。
SemaphoreHandle_t xSemaphoreCreateMutex( void )
参数:
无
返回值:
成功,返回对应互斥量的句柄;
失败,返回 NULL 。

3、STM32CubeMX配置

新建三个任务分别为Task_H、Task_M、Task_L优先级分别设置为osPriorityAboveNormal、osPriorityNormal、osPriorityBelowNormal。

互斥量配置:Mutexes -> Add -> ok

此时生成文件会报错,内存不足,将内存变成5000

4、优先级翻转测试

4.1 Task_H

void StartTask_H(void *argument)
{
  /* USER CODE BEGIN StartTask_H */
  /* Infinite loop */
  for(;;)
  {
	  xSemaphoreTake(myBinarySem01Handle, portMAX_DELAY);
	  printf("TaskH:在房间睡觉!~~~\r\n");
	  HAL_Delay(1000);
	  printf("TaskH:睡醒了!~~~\r\n");
	  xSemaphoreGive(myBinarySem01Handle);
	  osDelay(1000);
  }
  /* USER CODE END StartTask_H */
}

4.2 Task_M 

void StartTask_M(void *argument)
{
  /* USER CODE BEGIN StartTask_M */
  /* Infinite loop */
  for(;;)
  {
	  
	  printf("TaskM:打王者呢!~~\r\n");
      osDelay(1000);
  }
  /* USER CODE END StartTask_M */
}

4.3 Task_L 

void StartTask_L(void *argument)
{
  /* USER CODE BEGIN StartTask_L */
  /* Infinite loop */
  for(;;)
  {
	   xSemaphoreTake(myBinarySem01Handle, portMAX_DELAY);
       printf("TaskL:在房间睡觉呢!!!\r\n");
       HAL_Delay(3000);
       printf("TaskL:睡醒了,真舒服~~~\r\n");
       xSemaphoreGive(myBinarySem01Handle);
       osDelay(1000);
  }
  /* USER CODE END StartTask_L */
}

测试结果分析:

 需要注意:HAL_Delay函数使用系统时钟来进行延时,并且在延时期间会阻塞整个处理器,也就是说,它会使处理器暂时停止执行其他任务和代码。

5、通过互斥量解决优先级翻转测试

将Task_H、Task_L二值信号量句柄通过互斥量句柄进行替换:

5.1 Task_H

void StartTask_H(void *argument)
{
  /* USER CODE BEGIN StartTask_H */
  /* Infinite loop */
  for(;;)
  {
	  xSemaphoreTake(myMutex01Handle, portMAX_DELAY);
	  printf("TaskH:在房间睡觉!~~~\r\n");
	  HAL_Delay(1000);
	  printf("TaskH:睡醒了!~~~\r\n");
	  xSemaphoreGive(myMutex01Handle);
	  osDelay(1000);
  }
  /* USER CODE END StartTask_H */
}

5.2 Task_L

void StartTask_L(void *argument)
{
  /* USER CODE BEGIN StartTask_L */
  /* Infinite loop */
  for(;;)
  {
	   xSemaphoreTake(myMutex01Handle, portMAX_DELAY);
       printf("TaskL:在房间睡觉呢!!!\r\n");
       HAL_Delay(3000);
       printf("TaskL:睡醒了,真舒服~~~\r\n");
       xSemaphoreGive(myMutex01Handle);
       osDelay(1000);
  }
  /* USER CODE END StartTask_L */
}

5.3 测试

通过互斥量解决优先级翻转!

上文如有错误恳请各位大佬指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值