原创
十一、freeRTOS 优先级翻转与互斥信号量
优先级翻转
优先级翻转简介:
就是高优先级的任务运行起来的效果好像成了低优先级,而低优先级比高优先级先运行。
优先级翻转如下所示:
优先级翻转过程:
为什么会发生优先级翻转?
因为两个任务(L和H)使用了同一个二值信号量,而在这两个任务之间,又有一个中等优先级的任务M,在这种情况下就容易发生优先级翻转。主要就是因为二值信号量产生的,低优先级任务L占用了信号量没有释放,导致高优先级任务请求信号量时无效,此时高优先级任务无法运行。
实验设计
总体思路是,任务L和任务H都请求信号量,当接收到信号量时,任务H立马释放信号量,而任务L做软件延时占用一段时间后再释放信号量,看程序的执行流程。测试代码如下所示:
void start_task(void *pvParameters);
void low_task(void *pvParameters);
void middle_task(void *pvParameters);
void high_task(void *pvParameters);
#define START_TASK_SIZE 256
#define START_TASK_PRIO 1
TaskHandle_t start_Task_Handle;
#define LOW_TASK_SIZE 256
TaskHandle_t low_task_Handle;
#define MIDDLE_TASK_SIZE 256
#define MIDDLE_TASK_PRIO 3
TaskHandle_t middle_task_Handle;
#define HIGH_TASK_SIZE 256
TaskHandle_t high_task_Handle;
SemaphoreHandle_t binary_semphr = NULL;
xTaskCreate((TaskFunction_t )start_task,
(uint16_t )START_TASK_SIZE,
(UBaseType_t )START_TASK_PRIO,
(TaskHandle_t * )&start_Task_Handle);
void start_task(void *pvParameters)
binary_semphr = xSemaphoreCreateBinary();
if (binary_semphr != NULL)
xSemaphoreGive(binary_semphr);
xTaskCreate((TaskFunction_t )low_task,
(uint16_t )LOW_TASK_SIZE,
(UBaseType_t )LOW_TASK_PRIO,
(TaskHandle_t * )&low_task_Handle);
xTaskCreate((TaskFunction_t )middle_task,
(uint16_t )MIDDLE_TASK_SIZE,
(UBaseType_t )MIDDLE_TASK_PRIO,
(TaskHandle_t * )&middle_task_Handle);
xTaskCreate((TaskFunction_t )high_task,
(uint16_t )HIGH_TASK_SIZE,
(UBaseType_t )HIGH_TASK_PRIO,
(TaskHandle_t * )&high_task_Handle);
vTaskDelete(start_Task_Handle);
void low_task(void *pvParameters)
if (binary_semphr != NULL)
error_state = xSemaphoreTake(binary_semphr, portMAX_DELAY);
if (error_state == pdTRUE)
printf("\n低优先级任务获取到信号量,正在占用...");
printf("\n低优先级任务获取信号量失败");
for (limit = 0; limit < 5000000; limit++)
printf("\n低优先级任务占用信号量结束,即将释放");
xSemaphoreGive(binary_semphr);
void middle_task(void *pvParameters)
void high_task(void *pvParameters)
if (binary_semphr != NULL)
printf("\n高优先级任务正在等待信号量...");
xSemaphoreTake(binary_semphr, portMAX_DELAY);
printf("\n高优先级任务获取到信号量,即将释放...");
xSemaphoreGive(binary_semphr);
程序运行结果如下所示:
互斥信号量
互斥信号量简介:
创建互斥信号量:
测试实验:修改上一个优先级翻转的实验,看测试结果。
修改过程:将使用二值信号量的地方修改成使用互斥信号量。
修改如下:
void start_task(void *pvParameters)
mutex_semphr = xSemaphoreCreateMutex();
if (mutex_semphr != NULL)
xSemaphoreGive(mutex_semphr);
xTaskCreate((TaskFunction_t )low_task,
(uint16_t )LOW_TASK_SIZE,
(UBaseType_t )LOW_TASK_PRIO,
(TaskHandle_t * )&low_task_Handle);
xTaskCreate((TaskFunction_t )middle_task,
(uint16_t )MIDDLE_TASK_SIZE,
(UBaseType_t )MIDDLE_TASK_PRIO,
(TaskHandle_t * )&middle_task_Handle);
xTaskCreate((TaskFunction_t )high_task,
(uint16_t )HIGH_TASK_SIZE,
(UBaseType_t )HIGH_TASK_PRIO,
(TaskHandle_t * )&high_task_Handle);
vTaskDelete(start_Task_Handle);
void low_task(void *pvParameters)
if (mutex_semphr != NULL)
error_state = xSemaphoreTake(mutex_semphr, portMAX_DELAY);
if (error_state == pdTRUE)
printf("\n低优先级任务获取到信号量,正在占用...");
printf("\n低优先级任务获取信号量失败");
for (limit = 0; limit < 5000000; limit++)
printf("\n低优先级任务占用信号量结束,即将释放");
xSemaphoreGive(mutex_semphr);
void middle_task(void *pvParameters)
void high_task(void *pvParameters)
if (mutex_semphr != NULL)
printf("\n高优先级任务正在等待信号量...");
xSemaphoreTake(mutex_semphr, portMAX_DELAY);
printf("\n高优先级任务获取到信号量,即将释放...");
xSemaphoreGive(mutex_semphr);
测试效果如下:
递归互斥信号量:
转载于:https://blog.csdn.net/dingyc_ee/article/details/104115367
文章评论(0条评论)
登录后参与讨论