FreeRtos(6)-----互斥量优先级继承机制

接上篇的优先级翻转

互斥量

#include "stm32f10x.h"
#include "led.h"
#include "stdio.h"
#include "usart1.h"
#include "systick.h"
#include "delay.h"
#include "my_key.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

#define QUEUE_LEN 8
#define QUEUE_SIZE 8
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t hight_Task_Handle = NULL;/* server 任务句柄 */
static TaskHandle_t med_Task_Handle = NULL;/* client 任务句柄 */
static TaskHandle_t low_Task_Handle = NULL;/* client 任务句柄 */
static void AppTaskCreate(void);/* 用于创建任务 */
static void low_Task(void* pvParameters);
static void med_Task(void* pvParameters);
static void hight_Task(void* parameter);

SemaphoreHandle_t MuxSem_Handle =NULL;//二值信号量句柄
int main(void)
{
 BaseType_t xReturn = pdPASS;//创建任务返回值
 NVIC_SetPriorityGrouping(3);
 usrat1_config();
 systick_config();
 key_init();
 led_config();
 printf("hello\r\n");

 //创建任务
 /* 创建 AppTaskCreate 任务 */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,/* 任务入口函数 */
												(const char *)"AppTaskCreate",/* 任务名字 */
												(uint16_t )512,
												(void *)NULL,
												(UBaseType_t )1,
												(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
	
 /* 启动任务调度 */
	if (pdPASS == xReturn) 
	{
	  vTaskStartScheduler(); 
	}
	else 
	{
	return -1; 
	}
	 
 while (1); /* 正常不会执行到这里 */
}
static void AppTaskCreate(void)
{
 BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
 taskENTER_CRITICAL();
	
	MuxSem_Handle = xSemaphoreCreateMutex();//创建二值信号量
	xSemaphoreGive(MuxSem_Handle);//释放
	
 xReturn = xTaskCreate((TaskFunction_t )hight_Task,/* 任务入口函数 */
												(const char *)"hight_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )4,
												(TaskHandle_t* )&hight_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("hight任务创建成功\r\n");
 }
 
  xReturn = xTaskCreate((TaskFunction_t )med_Task,/* 任务入口函数 */
												(const char *)"med_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )3,
												(TaskHandle_t* )&med_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("med任务创建成功\r\n");
 }
   xReturn = xTaskCreate((TaskFunction_t )low_Task,/* 任务入口函数 */
												(const char *)"low_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )2,
												(TaskHandle_t* )&low_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("low任务创建成功\r\n");
 }
 
 
 
 
vTaskDelete(AppTaskCreate_Handle); //删除 AppTaskCreate 任务 
taskEXIT_CRITICAL();//退出临界区

}
//定义一个任务
static void hight_Task(void* parameter)
{

 while(1)
 {
	printf("高优申请\r\n");
	xSemaphoreTake(MuxSem_Handle,portMAX_DELAY);//申请
  printf("高优获得\r\n");
	printf("hight_run\r\n");
	printf("高优释放\r\n");
	xSemaphoreGive(MuxSem_Handle);//释放
	vTaskDelay(500);
 }
}
static void med_Task(void* parameter)
{
	while(1)
	{
		printf("1\r\n");
		vTaskDelay(500);
	
	}

}

static void low_Task(void* parameter)
{
 uint32_t i=0;
 while(1)
 {
	xSemaphoreTake(MuxSem_Handle,portMAX_DELAY);//申请
	 printf("低优获得\r\n");
	 for(i=0;i<2000000;i++)
	 {
	  taskYIELD();//发起任务调度
	 
	 }
	xSemaphoreGive(MuxSem_Handle);//释放
	vTaskDelay(500);
 } 
}

运行结果:
在这里插入图片描述
可以看到,当高优先级任务运行到延时后,转到中优先级,中优先级遇到延时后,转到低优先级,低优先级里面运行到调度函数,高优先级申请不到资源阻塞。接着中优先级并没有被调度运行,而是依旧运行低优先级任务。这就出现了优先级继承。

FreeRTOS提供的互斥可以通过优先级继承算法来解决优先级翻转问题。优先级继承算法是指,当一个低优先级任务占用了某个资源时,该任务的优先级会被临时提升到与等待该资源的高优先级任务中最高优先级任务相等。这样可以避免高优先级任务被中间优先级任务抢占的情况发生。当低优先级任务释放该资源时,它的优先级会恢复到初始设定值。这种优先级继承机制确保了高优先级任务进入阻塞状态的时间尽可能短,同时降低了优先级翻转带来的影响。因此,对于保护临界资源,建议使用FreeRTOS互斥来实现优先级继承机制。 需要注意的是,互斥优先级继承机制只在任务中起作用,在中断服务函数中无效。因此,在中断服务函数中不能使用互斥来解决优先级翻转问题。 在某些场景下,当低优先级任务占用了某个资源时,即使有高优先级任务需要使用该资源,高优先级任务也必须等待低优先级任务释放该资源。这种情况被称为"优先级翻转"。<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/weixin_47077788/article/details/125983165)[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_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值