FreeRTOS总结
文章目录
- 前言
- 一、浅浅了解优先级翻转
- 二、模拟 优先级翻转实验
-
- 总结
前言
在使用二值信号量的时候会遇到很常见的一个问题——优先级翻转,优先级翻转在可剥夺
内核中是非常常见的,在实时系统中不允许出现这种现象,这样会破坏任务的预期顺序,可能
会导致严重的后果。
提示:以下是本篇文章正文内容,下面案例可供参考
一、浅浅了解优先级翻转
例如:三个不同优先级的任务——低任务、中任务、高任务
创建二值信号量,然后释放一次信号量。
低任务获取信号量,长时间不释放,占住了高任务的资源。
高任务获取信号量,但是此时信号量被低任务占用着,高任务只能等待。但是等待过程中,中任务是一直运行的。出现了优先级反转。
二、模拟 优先级翻转实验
1.代码
**注意:**低优先级和高优先级均要获取二值信号,并且低优先级要长时间获取信号量,模拟占取高优先级的二值信号量。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "beep.h"
#include "malloc.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#define START_TASK_PRIO 1
#define START_STK_SIZE 256
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);
#define LOW_TASK_PRIO 2
#define LOW_STK_SIZE 256
TaskHandle_t LowTask_Handler;
void low_task(void *pvParameters);
#define MIDDLE_TASK_PRIO 3
#define MIDDLE_STK_SIZE 256
TaskHandle_t MiddleTask_Handler;
void middle_task(void *pvParameters);
#define HIGH_TASK_PRIO 4
#define HIGH_STK_SIZE 256
TaskHandle_t HighTask_Handler;
void high_task(void *pvParameters);
SemaphoreHandle_t BinarySemaphore;
int lcd_discolor[14]={ WHITE, BLACK, BLUE, BRED,
GRED, GBLUE, RED, MAGENTA,
GREEN, CYAN, YELLOW,BROWN,
BRRED, GRAY };
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
delay_init();
uart_init(115200);
LED_Init();
KEY_Init();
BEEP_Init();
LCD_Init();
my_mem_init(SRAMIN);
POINT_COLOR = RED;
LCD_ShowString(30,10,200,16,16,"ATK STM32F103/407");
LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 14-3");
LCD_ShowString(30,50,200,16,16,"Priority Overturn");
LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,90,200,16,16,"2016/11/25");
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();
BinarySemaphore=xSemaphoreCreateBinary();
if(BinarySemaphore!=NULL)xSemaphoreGive(BinarySemaphore);
xTaskCreate((TaskFunction_t )high_task,
(const char* )"high_task",
(uint16_t )HIGH_STK_SIZE,
(void* )NULL,
(UBaseType_t )HIGH_TASK_PRIO,
(TaskHandle_t* )&HighTask_Handler);
xTaskCreate((TaskFunction_t )middle_task,
(const char* )"middle_task",
(uint16_t )MIDDLE_STK_SIZE,
(void* )NULL,
(UBaseType_t )MIDDLE_TASK_PRIO,
(TaskHandle_t* )&MiddleTask_Handler);
xTaskCreate((TaskFunction_t )low_task,
(const char* )"low_task",
(uint16_t )LOW_STK_SIZE,
(void* )NULL,
(UBaseType_t )LOW_TASK_PRIO,
(TaskHandle_t* )&LowTask_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
void high_task(void *pvParameters)
{
u8 num;
POINT_COLOR = BLACK;
LCD_DrawRectangle(5,110,115,314);
LCD_DrawLine(5,130,115,130);
POINT_COLOR = BLUE;
LCD_ShowString(6,111,110,16,16,"High Task");
while(1)
{
vTaskDelay(500);
num++;
printf("high task Pend Sem\r\n");
xSemaphoreTake(BinarySemaphore,portMAX_DELAY);
printf("high task Running!\r\n");
LCD_Fill(6,131,114,313,lcd_discolor[num%14]);
LED1=!LED1;
xSemaphoreGive(BinarySemaphore);
vTaskDelay(500);
}
}
void middle_task(void *pvParameters)
{
u8 num;
POINT_COLOR = BLACK;
LCD_DrawRectangle(125,110,234,314);
LCD_DrawLine(125,130,234,130);
POINT_COLOR = BLUE;
LCD_ShowString(126,111,110,16,16,"Middle Task");
while(1)
{
num++;
printf("middle task Running!\r\n");
LCD_Fill(126,131,233,313,lcd_discolor[13-num%14]);
LED0=!LED0;
vTaskDelay(1000);
}
}
void low_task(void *pvParameters)
{
static u32 times;
while(1)
{
xSemaphoreTake(BinarySemaphore,portMAX_DELAY);
printf("low task Running!\r\n");
for(times=0;times<5000000;times++)
{
taskYIELD();
}
xSemaphoreGive(BinarySemaphore);
vTaskDelay(1000);
}
}
总结
今天就大概了解了什么是优先级翻转的现象。
当一个低优先级任务和一个高优先级任务同时使用同一个信号量,而系统中还有其他中等优先级任务时。如果低优先级任务获得了信号量,那么高优先级的任务就会处于等待状态,但是,中等优先级的任务可以打断低优先级任务而先于高优先级任务运行(此时高优先级的任务在等待信号量,所以不能运行),这是就出现了优先级翻转的现象。
那如何解决这个问题呢?下篇的博客会告诉你。
继续加油!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)