【FreeRTOS】12.STM32移植-优先级翻转

优先级翻转

高优先级的任务由于等待信号量而被挂起,导致不需要信号量的低优先级任务先运行。

实验目的

在使用二值信号量的时候会存在优先级翻转的问题,本实验通过模拟的方式实现优先级翻转,观察优先级翻转对抢占式内核的影响。

实验设计

设置了四个任务。

start_task:创建3个任务

high_task:高优先级任务,获取二值信号量触发

middle_task:中优先级任务,简单引用任务

low_task:低优先级任务,和高优先级任务一样需获取同一个二值信号量才能触发,占用信号量的时间比较长

实验代码:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#include "key.h"
#include "queue.h"
#include "timer.h"
#include "semphr.h"
/************************************************

************************************************/

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);


//任务优先级
#define LOW_TASK_PRIO		2
//任务堆栈大小	
#define LOW_STK_SIZE 		128  
//任务句柄
TaskHandle_t Low_Handler;
//任务函数
void low_task(void *pvParameters);

//任务优先级
#define MIDDLE_TASK_PRIO		3
//任务堆栈大小	
#define MIDDLE_STK_SIZE 		128  
//任务句柄
TaskHandle_t Middle_Handler;
//任务函数
void middle_task(void *pvParameters);

//任务优先级
#define HIGH_TASK_PRIO		4
//任务堆栈大小	
#define HIGH_STK_SIZE 		128  
//任务句柄
TaskHandle_t High_Handler;
//任务函数
void high_task(void *pvParameters);

SemaphoreHandle_t SemphrHandle;         // 二值信号量句柄

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	 
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	KEY_Init();	
	
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
	SemphrHandle = xSemaphoreCreateBinary();
	if(SemphrHandle != NULL)
	{
		xSemaphoreGive(SemphrHandle);// 创建成功,释放信号量
	}
	else
	{
		printf("xSemaphoreCreateCounting   Failed!\r\n");
	}
	xTaskCreate((TaskFunction_t) low_task,
				(const char *  ) "low_task",
				(uint16_t      ) LOW_STK_SIZE,
				(void *        ) NULL,
				(UBaseType_t   ) LOW_TASK_PRIO,
				(TaskHandle_t* ) &Low_Handler);
				
	xTaskCreate((TaskFunction_t) middle_task,
				(const char *  ) "middle_task",
				(uint16_t      ) MIDDLE_STK_SIZE,
				(void *        ) NULL,
				(UBaseType_t   ) MIDDLE_TASK_PRIO,
				(TaskHandle_t* ) &Middle_Handler);
				
	xTaskCreate((TaskFunction_t) high_task,
				(const char *  ) "high_task",
				(uint16_t      ) HIGH_STK_SIZE,
				(void *        ) NULL,
				(UBaseType_t   ) HIGH_TASK_PRIO,
				(TaskHandle_t* ) &High_Handler);
							
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//任务函数
void low_task(void *pvParameters)
{
	int i = 0;
	while(1)
	{
		xSemaphoreTake(SemphrHandle,portMAX_DELAY); // 请求信号量
		printf("1_low task is running!\r\n");
		
		for(;i<2000000;i++) // 延时占用
		{
			//delay_us(1000);
			taskYIELD();// 任务切换
		}
		
		xSemaphoreGive(SemphrHandle);// 释放信号量
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

//任务函数
void middle_task(void *pvParameters)
{
	while(1)
	{
		
		printf("2_middle task is running!\r\n");
		
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

//任务函数
void high_task(void *pvParameters)
{

	while(1)
	{
		printf("high task pend!!!\r\n");
		xSemaphoreTake(SemphrHandle,portMAX_DELAY); // 请求信号量
		printf("3_high task is running!\r\n");
		
		xSemaphoreGive(SemphrHandle);// 释放信号量
		
		
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}
实验现象:
high task pend!!!
3_high task is running!
2_middle task is running!
1_low task is running!
high task pend!!!
2_middle task is running!
2_middle task is running!
2_middle task is running!
2_middle task is running!
3_high task is running!
2_middle task is running!
high task pend!!!
3_high task is running!
1_low task is running!
2_middle task is running!
high task pend!!!
3_high task is running!
1_low task is running!

high task pend!!!高任务在申请请求时,由于被低任务占用信号量,导致2_middle task is running!多次执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值