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

嵌入式八股文(四)FreeRTOS篇

系列文章目录

嵌入式八股文(一)C语言篇
嵌入式八股文(二)Linux应用篇
嵌入式八股文(三)Linux驱动篇
嵌入式八股文(四)FreeRTOS篇


文章目录

  • 系列文章目录
  • 一、内核
    • 1.1 FreeRTOS启动流程
    • 1.2 内核的基本组成及内核对象
    • 1.3 FreeRTOS调度算法
    • 1.4 哪些事件会触发任务调度
  • 二、 内存管理
    • 2.1 五种内存管理机制
    • 2.2 如何避免内存泄露
  • 三、同步及通讯
    • 3.1. 优先级反转与解决方案
    • 3.2. 临界区和临界资源
    • 3.3. 二值信号量和互斥量的区别
  • 四、其他
    • 4.1 实时操作系统的优势及特点
    • 4.2 FreeRTOS如何移植及对代码裁剪
    • 4.3 空闲任务是否是必须的及其作用


一、内核

1.1 FreeRTOS启动流程

  1. 系统给上电后,首先会调用复位函数Reset_Handle,然后调用__main来初始化堆栈,最后跳转到C中的main函数中。
  2. main函数中会进行系统初始化(比如初始化系统时钟)和外设始化(比如初始化I2C、SPI等),并创建相应的任务,所有的任务都创建完成后则调用vTaskStartScheduler()函数来启动任务调度器,任务调度器是FreeRTOS的核心。
  3. 开启任务调度函数vTaskStartScheduler()中会执行如下操作:
    ① 创建空闲任务、定时器服务任务、关闭中断;
    ② 设置PendSV和Systick为最低优先级的中断,并且开启Systick中断;
    ③ 初始化一些全局变量,将变量xSchedulerRuning设置为True,表示调度器开始运行;
    ④ 初始化时钟节拍计数器、初始化临界区嵌套计数器,如果ARM内核支持FPU,还会使能FPU;
    ⑤ 最后调用vPortStartFirstTask()函数运行第一个任务(任务优先级最高的任务),这是一个汇编函数,通过SVC中断来启动第一个任务。(整个FreeRTOS中只在这里使用了一次SVC中断)

1.2 内核的基本组成及内核对象

  FreeRTOS 内核的核心组成包括任务调度内存管理通信机制中断处理时间管理,其设计目标是为嵌入式系统提供高效、可靠的多任务环境。

1.3 FreeRTOS调度算法

  FreeRTOS 支持两种调度模式:抢占式调度(默认,按优先级)和协作式调度(任务必须主动释放资源才会切换),而时间片轮转是抢占式调度中的一个子机制,通过时间片轮转(默认每个 tick 切换一次)实现分时共享 CPU。
  时间片轮转调度在以下情况会发生任务切换

  1. 进程使用互斥锁(被动切换),互斥锁不可用时
  2. 进程主动休眠(主动切换)
  3. 进程被撤销(强制切换)
  4. 进程当前时间片使用完(强制切换)

1.4 哪些事件会触发任务调度

  1. 任务挂起或删除:当前任务调用vTaskSuspend()或vTaskDelete()后,会立即让出CPU,调度器选择其他就绪任务执行
  2. 任务优先级变化:当一个高优先级任务变为就绪状态(例如通过信号量释放、消息队列接收等),当前任务可能会被抢占。
  3. 系统节拍中断: 每次系统节拍(tick)中断都会触发调度器,检查是否有就绪任务需要切换(如时间片轮转的场合)
  4. 延时函数调用: 当任务调用vTaskDelay()或vTaskDelayUntil()时,任务进入阻塞状态,调度器会选择其他任务

二、 内存管理

2.1 五种内存管理机制

  • heap_1.c:只分配不删除,只有pvPortMalloc,没有实现vPortFree;
  • heap_2.c:最佳匹配算法,但不会合并相邻的空闲内存,碎片化严重;
  • heap_3.c:使用标准C库里的malloc、free函数,configTOTAL_HEAP_SIZE不再起作用;
  • heap_4.c:首次适应算法,会把相邻空闲内存合并为一个大的空闲内存,可以较少内存的碎片化;
  • heap_5.c:分配内存、释放内存的算法跟Heap_4是一样的,不局限于管理一个大数组:它可以管理多块、分隔开的内存。

2.2 如何避免内存泄露

  1. 选择合适内存方案:1无法动态释放,3会带来碎片化,常用4或者5
  2. 正确释放动态分配的资源
  3. 避免创建未使用的任务及资源,启用时进行内存统计:采用vTaskList()
  4. 采用configASSERT()捕获

三、同步及通讯

3.1. 优先级反转与解决方案

  优先级反转是指低优先级任务持有高优先级任务所需的资源(如互斥锁),导致高优先级任务被阻塞,而中优先级任务抢占 CPU,形成“反转”。
  可以通过优先级继承(低优先级任务的优先级会被临时提升)或者使用消息队列和信号量来管理资源来解决这种情况。

3.2. 临界区和临界资源

 临界区:指访问共享资源的代码段,必须保证一次只允许一个任务进入,以防止数据竞争。
 临界资源:被多个任务共享且可能引发竞争的资源,访问它时需要保护机制(如互斥锁)。

3.3. 二值信号量和互斥量的区别

  互斥量是二值信号量的的特殊形式(互斥信号量其实就是一个拥有优先级继承的二值信号量),其主要差距如下所示:

二值信号量互斥量
应用场景同步保护共享资源
所有权any谁申请谁释放
优先级继承不支持支持(解决优先级反转问题)
初始状态通常初始化为 0(未被获取)初始化为 1(未被获取)

四、其他

4.1 实时操作系统的优势及特点

  在常用的前后台系统包含有一个后台任务和一个前台任务,整个系统结构简单,但对时间敏感的任务响应较差。而在实时操作系统(RTOS)中,多个任务可以被调度,系统通过任务调度器管理任务的执行顺序。RTOS可以保证高优先级任务得到及时的处理,更适合复杂系统中的实时响应需求。实时系统的基本特性如下所示:
确定性:系统能够在确定的时间内完成指定任务,确保任务按时完成。
可预测性:系统能够预测在特定条件下的行为,保证在任何情况下系统都能做出可预见的响应。
高可靠性:系统能够长时间运行且不出错,尤其在关键应用中,可靠性至关重要。

4.2 FreeRTOS如何移植及对代码裁剪

FreeRTOS的移植

  1. 在源程序中创建freertos文件夹
  2. 在文件夹中创建src存放source的核心文件,就是.c文件
  3. 在文件夹中创建port存放MenMang内存管理文件和RVDS处理器架构相关代码
  4. 最后再将include头文件和FreeRTOSConfig.h配置文件移植进来即可

FreeRTOS的裁剪

  1. task.c和list.c是必须的,其他的核心文件按需选择即可;
  2. RVDS中只留下我们使用到的芯片的即可,其他可以删除;
  3. 内存管理有5个文件,我们一般留heap_4.c,其他可以删除

4.3 空闲任务是否是必须的及其作用

  FreeRTOS 的空闲任务(Idle Task) 是必须存在的,它是 FreeRTOS 调度器自动创建的一个默认任务(优先级最低,通常为 0)。它的核心作用是确保系统始终有一个可运行的任务,维持调度器的正常运转。以下是它的主要作用:

  1. 防止处理器空转:其他任务没有工作要执行时,就会执行空闲任务;
  2. 释放内存:调用 vTaskDelete() 删除任务时,实际内存释放由空闲任务完成;
  3. 执行低功耗模式;
  4. 执行钩子函数:空闲任务钩子函数必须是非阻塞的。

http://www.kler.cn/a/614158.html

相关文章:

  • Java基于SpringBoot的网络云端日记本系统,附源码+文档说明
  • 蓝桥杯[每日一题] 真题:管道(java版)
  • 基于飞腾FT2000/4的全国产标准6U VPX板卡,支持银河麒麟
  • 1500 字节 MTU | 溯源 / 技术权衡 / 应用影响
  • 知识图谱初相识(概念理解篇)
  • Zookeeper特性与节点数据类型
  • 告别桌面杂乱与充电焦虑,移速165W百变桌面充电站首发体验
  • TDengine 中的异常恢复
  • vue搭建一个树形菜单项目
  • std::countr_zero
  • 如何让AI套用现有ppt模板,并通过改文字批量生成新的ppt?【翻车版】
  • 【动态规划篇】- 路径问题
  • uniapp用法--uni.navigateTo 使用与参数携带的方式示例(包含复杂类型参数)
  • 【AI知识】深度学习中模型参数初始化方法介绍
  • 【Hugging Face 开源库】Diffusers 库 —— 扩散模型
  • 【STM32】知识点介绍二:GPIO引脚介绍
  • Markdown 和 Microsoft Word对比
  • C++细节知识for面试
  • 【老电脑翻新】华硕A456U(换电池+换固态+光驱换机械+重装系统+重装系统后开始菜单失灵问题解决)
  • 【附代码】【MILP建模】3D装箱问题(3D-Bin Packing Problem)