当前位置: 首页 > web >正文

FreeRTOS—优先级翻转问题

文章目录

  • 一、优先级翻转简介
  • 二、实验
    • 2.1.实验设计
    • 2.2.软件设计

一、优先级翻转简介

优先级翻转顾名思义就是:高优先级的任务变成最后执行,低优先级的任务反而优先执行。优先级翻转在抢占式内核中是很常见的问题,但是在实时操作系统中是不允许出现优先级翻转的,因为优先级翻转会破环任务的预期顺序,可能会导致未知的严重后果。在使用二值信号量的时候,经常会遇到优先级翻转问题。

二、实验

2.1.实验设计

本实验设计四个任务:

  • start_task:创建其他任务
  • high_task:高优先级任务,会获取二值信号量,获取成功以后打印提示信息,处理完后释放信号量
  • middle_task:中等优先级任务,简单的应用任务
  • low_task:低优先级任务,和高优先级任务操作一致,不同的是低优先级任务占用信号量的时间久一点

2.2.软件设计

在入口函数里面创建二值信号量,并释放一个资源给下面两个任务:

void freertos_demo(void)
{semphr_handle = xSemaphoreCreateBinary();if(semphr_handle != NULL){printf("二值信号量创建成功\r\n");}xSemaphoreGive(semphr_handle);xTaskCreate((TaskFunction_t)    start_task,(char*)             "start_task",(uint16_t)          START_TASK_STACK_SIZE,(void*)             NULL,(UBaseType_t)       START_TASK_PRIO,(TaskHandle_t*)     &start_task_handler);vTaskStartScheduler();  		
}

下面是三个不同优先级的任务,high_task 函数优先级最高,依次递减:

void low_task(void *pvParameters)
{while(1){xSemaphoreTake(semphr_handle, portMAX_DELAY);	printf("低优先级任务获取信号量成功\r\n");printf("低优先级任务正在运行\r\n");delay_ms(5000);printf("低优先级任务释放信号量\r\n");xSemaphoreGive(semphr_handle);vTaskDelay(1000);}
}void middle_task(void *pvParameters)
{uint8_t i = 0;while(1){printf("中等任务运行:%d\r\n",++i);vTaskDelay(1000);}
}void high_task(void *pvParameters)
{while(1){xSemaphoreTake(semphr_handle, portMAX_DELAY);printf("高优先级任务获取信号量成功\r\n");printf("高优先级任务正在运行\r\n");delay_ms(1000);printf("高优先级任务释放信号量\r\n");xSemaphoreGive(semphr_handle);vTaskDelay(1000);}
}

下图是运行的结果图:

在这里插入图片描述

根据上图分析,二值信号量创建成功并释放了一个资源之后,自然高优先级任务就优先获取该信号量,运行结束并释放信号量之后,就到中等优先级任务运行了,中等优先级任务运行不受信号量控制,因此中等优先级任务运行按 1 秒的节奏运行,最后到低优先级任务获取信号量,但是该任务需要运行 5 秒,才能释放信号量给高优先级运行,这 5 秒之内,中等优先级任务也就运行了 5 次,因此就出现了优先级翻转。
为什么低优先级任务里面用了delay_ms(5000)函数,CPU会跑去运行中等优先级任务呢?

  • 这是因为被 SysTick 中断打断,导致调度器仍能切换任务,该函数里面操作的也是 SysTick 的寄存器
http://www.xdnf.cn/news/16383.html

相关文章:

  • vue项目入门
  • 【C++避坑指南】vector迭代器失效的八大场景与解决方案
  • haproxy七层代理(原理)
  • 从0开始学习R语言--Day57--SCAD模型
  • 深入浅出设计模式——创建型模式之简单工厂模式
  • Hive【Hive架构及工作原理】
  • 如何高效通过3GPP官网查找资料
  • JAVA + 海康威视SDK + FFmpeg+ SRS 实现海康威视摄像头二次开发
  • 服务器托管:网站经常被攻击该怎么办?
  • 学习游戏制作记录(克隆技能)7.25
  • 秋招Day19 - 分布式 - 分布式锁
  • 初识决策树-理论部分
  • 肺癌预测模型实战案例
  • 【自动化运维神器Ansible】Ansible常用模块之Copy模块详解
  • 文件包含学习总结
  • 滑动窗口-7
  • 主要分布在背侧海马体(dHPC)CA1区域(dCA1)的时空联合细胞对NLP中的深层语义分析的积极影响和启示
  • ClickHouse 常用的使用场景
  • AWS WebRTC:我们的业务模式
  • [python][flask]flask蓝图使用方法
  • 【软件工程】构建软件合规防护网:双阶段检查机制的实践之道
  • Android studio自带的Android模拟器都是x86架构的吗,需要把arm架构的app翻译成x86指令?
  • FP16 和 BF16
  • 函数-变量的作用域和生命周期
  • 老题新解|奇偶数判断
  • 从Taro的Dialog.open出发,学习远程控制组件之【事件驱动】
  • OAuth 2.0 安全最佳实践 (RFC 9700) password 授权类型已经不推荐使用了,将在计划中移除
  • JS与Go:编程语言双星的碰撞与共生
  • vue2+node+express+MongoDB项目安装启动启动
  • go语言基础教程:【2】基础语法:基本数据类型(整形和浮点型)