FREERTOS学习笔记五-互斥锁

学习笔记五-互斥锁

1.实验内容

​ 互斥锁即优先级继承,其作用就是在H、L两个任务同时需要唯一资源时,且任务L需要先得到了使用权,这时需要提高L的优先级,让L尽快干完活,好让H用,避免因任务M打断任务L而导致任务L占用资源的时间过长。

​ 而递归互斥锁是可以在一个任务线程内使用。

​ 本次实验是在实验三的基础上进行修改,其中将按键任务的优先级更改为三者中的H;将任务三的优先级更改为三者中的M;将任务四的优先级更改为三者中的L。

2.CubeMX的配置

2.1添加互斥锁

请添加图片描述

2.2使能递归互斥锁

请添加图片描述

2.3添加递归互斥锁

请添加图片描述

2.4更改任务优先级

请添加图片描述

3.测试一 不添加互斥锁

3.1程序源码

按键

/* USER CODE END Header_StartKEY_Task */
void StartKEY_Task(void const * argument)
{
  /* USER CODE BEGIN StartKEY_Task */
  /* Infinite loop */
  for(;;)
  {
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
		{
			osDelay(10);//消抖
			osThreadSuspendAll();
			printf("KEY0按下\r\n");
			osThreadResumeAll();
			osThreadResume(myTask03Handle);//释放任务3
			osThreadResume(myTask04Handle);//释放任务4

		}
		while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
		{
			osDelay(10);
		}
    osDelay(1);
  }
  /* USER CODE END StartKEY_Task */
}

任务3

/* USER CODE END Header_StartTask03 */
void StartTask03(void const * argument)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
  for(;;)
  {
		osThreadSuspend(NULL);//将自己挂起
		osThreadSuspendAll();
		printf("我是任务1\r\n");
		osThreadResumeAll();
    osDelay(1);
  }
  /* USER CODE END StartTask03 */
}

任务4

/* USER CODE END Header_StartTask04 */
void StartTask04(void const * argument)
{
  /* USER CODE BEGIN StartTask04 */
  /* Infinite loop */
  for(;;)
  {		
		osThreadSuspend(NULL);//将自己挂起
		osThreadSuspendAll();
		printf("我是任务2\r\n");
		osThreadResumeAll();
		osDelay(1);
  }
  /* USER CODE END StartTask04 */
}

3.2测试结果

​ 由于任务3的优先级比任务4的优先级要,所以在按键任务释放任务3和任务4后,会先执行任务3其运行结果如下
请添加图片描述

4.测试二 添加互斥锁

4.1程序源码

按键

/* USER CODE END Header_StartKEY_Task */
void StartKEY_Task(void const * argument)
{
  /* USER CODE BEGIN StartKEY_Task */
  /* Infinite loop */
  for(;;)
  {
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
		{
			osDelay(10);//消抖
			osThreadSuspendAll();
			printf("KEY0按下\r\n");
			osThreadResumeAll();
			osThreadResume(myTask03Handle);//释放任务3
			osThreadResume(myTask04Handle);//释放任务4
			if(osMutexWait(myMutex01Handle,osWaitForever) == osOK)//获得互斥锁
			{
				osThreadSuspendAll();
				printf("获得成功byKEY\r\n");
				osThreadResumeAll();
			}
			else
			{
				osThreadSuspendAll();
				printf("获得失败byKEY\r\n");
				osThreadResumeAll();
			}
			
			if(osMutexRelease(myMutex01Handle) == osOK)
			{
				osThreadSuspendAll();
				printf("释放成功byKEY\r\n");
				osThreadResumeAll();
			}
			else
			{
				osThreadSuspendAll();
				printf("释放失败byKEY\r\n");
				osThreadResumeAll();
			}
		}
		while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
		{
			osDelay(10);
		}
    osDelay(1);
  }
  /* USER CODE END StartKEY_Task */
}

任务3

/* USER CODE END Header_StartTask03 */
void StartTask03(void const * argument)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
  for(;;)
  {
		osThreadSuspend(NULL);//将自己挂起
		osThreadSuspendAll();
		printf("我是任务1\r\n");
		osThreadResumeAll();
    osDelay(1);
  }
  /* USER CODE END StartTask03 */
}

任务4

/* USER CODE END Header_StartTask04 */
void StartTask04(void const * argument)
{
  /* USER CODE BEGIN StartTask04 */
  /* Infinite loop */
  for(;;)
  {
		if(osMutexWait(myMutex01Handle,osWaitForever) == osOK)//获得互斥锁
		{
			osThreadSuspendAll();
			printf("获得成功byTASK04\r\n");
			osThreadResumeAll();
		}
		else
		{
			osThreadSuspendAll();
			printf("获得失败byTASK04\r\n");
			osThreadResumeAll();
		}
		
		osThreadSuspend(NULL);//将自己挂起
		osThreadSuspendAll();
		printf("我是任务2\r\n");
		osThreadResumeAll();
		osDelay(1);
		
		if(osMutexRelease(myMutex01Handle) == osOK)
		{
			osThreadSuspendAll();
			printf("释放成功byTASK04\r\n");
			osThreadResumeAll();
		}
		else
		{
			osThreadSuspendAll();
			printf("释放失败byTASK04\r\n");
			osThreadResumeAll();
		}
  }
  /* USER CODE END StartTask04 */
}

4.2测试结果

​ 在按键key0未按下之前,任务4会先获得互斥锁然后挂起任务4

请添加图片描述

​ 当key0按键按下之后,由于任务4的获得互斥锁,那么任务4会获取与按键任务相同的优先级,测试结果如下

请添加图片描述

5.关键函数

osMutexWait(myMutex01Handle,osWaitForever)//获得互斥锁
osMutexRelease(myMutex01Handle)//释放互斥锁
在给出的代码中,引用和引用展示了在FreeRTOS中使用互斥锁的相关函数。具体来说,`osMutexWait`函数用于获得互斥锁,而`osMutexRelease`函数用于释放互斥锁。 在引用中的代码示例中,`StartKEY_Task`任务中的键盘按键检测部分使用了互斥锁来保护临界区。当检测到按键按下时,任务会先等待一段时间进行消抖处理,并挂起其他任务。然后,它会尝试获取互斥锁。如果获取成功,它会在控制台打印获得成功的消息,并释放互斥锁。如果获取失败,它会在控制台打印获得失败的消息。 另外,`StartTask04`任务中的代码示例也展示了互斥锁的使用。在该任务中,它会尝试获取互斥锁。如果获取成功,它会在控制台打印获得成功的消息,并将自己挂起。然后,它会在控制台打印任务2的消息,并释放互斥锁。如果获取失败,它会在控制台打印获得失败的消息。 综上所述,FreeRTOS中的互斥锁可以通过`osMutexWait`函数获取并通过`osMutexRelease`函数释放。它们可以用于保护多个任务对共享资源的访问,确保在任一时刻只有一个任务可以访问该资源。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [FREERTOS学习笔记-互斥锁](https://blog.csdn.net/qq_46384359/article/details/122775987)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值