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

FreeRTOS小记

管理寄存器

MSP:主栈指针,特权模式专用(RTOS 内核、中断服务程序)

  • RTOS 的内核:代码运行在 “特权模式”,所有内核操作的上下文(如调度器计算任务优先级、修改任务控制块 TCB)都存储在主栈中。
  • 中断服务程序(ISR):无论当前运行的是用户任务(用 PSP)还是内核代码(用 MSP),一旦发生中断,Cortex-M 内核会自动切换到 MSP,用主栈存储中断上下文(如断点处的寄存器值、中断服务程序的局部变量)。(避免中断处理污染任务栈导致任务崩溃)
  • 系统启动初始化:RTOS 启动前(如复位后),内核默认使用 MSP,主栈会先完成 “内核初始化”(如初始化 TCB 链表、堆内存、中断向量表),之后才创建第一个用户任务并切换到 PSP。

PSP:进程栈指针,用户模式专用:RTOS 用户任务的 “独立栈”

  • RTOS 用户任务运行:每个用户任务创建时,RTOS 会为其分配独立的进程栈空间(大小由用户在创建任务时指定),PSP 则指向 “当前正在运行的用户任务的栈顶”
  • 用户任务的上下文存储:用户任务中的函数调用、局部变量、任务级数据,均存储在该任务的进程栈中,与其他任务的栈完全独立。
  • 生命周期与任务一致
  • 权限受限:用户模式下使用 PSP 时,无法直接访问内核的特权资源(如内核私有寄存器、主栈数据),需通过 “系统调用(SVC 指令)” 切换到特权模式才能访问,提升系统安全性。

ARM Cortex-M寄存器组:

Cortex-M内存架构包含16个通用寄存器,其中R0-R12是13个32位的通用寄存器,另外三个寄存器是特殊用途,分别是R13(SP栈指针),R14(LR链接寄存器:保存函数或者子程序调用返回的地址),R15(PC程序计数器:下一个执行指令的地址)

任务调度

任务调度实现依赖任务状态管理调度策略上下文切换三大核心机制

任务控制块

每个任务都有自己的任务控制块TCB

typedef struct tskTaskControlBlock {StackType_t *pxTopOfStack;  // 任务栈顶指针(PSP值,关键!)ListItem_t xStateListItem;  // 用于将任务挂载到“状态列表”(就绪/阻塞等)UBaseType_t uxPriority;     // 任务优先级(0~ configMAX_PRIORITIES-1)StackType_t *pxStack;       // 任务栈基地址(栈空间起始位置)eTaskState eCurrentState;   // 任务当前状态(就绪/运行/阻塞/挂起)TickType_t xTicksToDelay;   // 阻塞延迟的时钟节拍数(用于延时唤醒)// 其他字段:任务名称、事件标志、内存管理块等
} tskTCB;
  • pxTopOfStack:最关键的字段,存储任务的栈指针(PSP 值)。任务切换时,调度器通过保存 / 加载该值,实现任务上下文的切换(见下文 “上下文切换”)。
  • xStateListItem:通过链表节点,将任务挂载到不同 “状态列表”(如就绪列表、阻塞列表),调度器通过遍历这些列表选择下一个运行的任务。
  • eCurrentState:标记任务状态(就绪:可被调度;运行:正在占用 CPU;阻塞:等待事件 / 延时;挂起:被强制暂停),调度器只从 “就绪列表” 中选择任务。

调度策略

  • 抢占式调度(任务优先级):高优先级抢占低优先级
  • 时间片轮转:同优先级任务按 “时间片” 轮流运行(每个任务运行固定时间后切换)
  • 合作式调度:任务主动调用 “阻塞函数”(如vTaskDelay())才会释放 CPU,否则一直运行

当调度器决定切换任务时,需要完成上下文切换(保存当前任务的上下文;加载新任务的上下文)

  • 保存当前任务(被切换出的任务)的上下文:将 CPU 寄存器(R0-R15、PSR 等)、栈指针(PSP)等数据存入该任务的 TCB(pxTopOfStack指向的栈空间)。
  • 加载新任务(被切换入的任务)的上下文:从新任务的 TCB 中读取之前保存的寄存器和 PSP 值,恢复到 CPU 中,让新任务从上次暂停的位置继续运行。

Cortex-M 内核通过PendSV(可悬起系统调用)异常实现上下文切换,原因是:PendSV 的优先级可配置为最低,确保在其他中断处理完成后再执行切换,避免打断紧急操作。

  1. 触发 PendSV 异常
  2. 进入 PendSV 异常服务程序(ISR):CPU 自动进入特权模式,切换到 MSP(主栈),开始执行 PendSV 的处理函数。
  3. 保存当前任务的上下文
    • 手动将 CPU 寄存器(R4-R11,因为 R0-R3 等已被硬件自动入栈)压入当前任务的栈(PSP 指向的栈空间)。
    • 将当前 PSP 值更新到当前任务的 TCB。
  4. 查找下一个要运行的任务:调度器从就绪列表中找到最高优先级的就绪任务,获取其 TCB。
  5. 加载新任务的上下文
    • 从TCB中读取 PSP 值,更新到 PSP 寄存器。
    • 从新任务的栈中弹出之前保存的 R4-R11 寄存器值,恢复到 CPU 中。
  6. 退出 PendSV 异常:CPU 自动从新任务的栈中恢复 R0-R3、LR、PC 等寄存器,切换到用户模式,新任务开始运行。
关键:栈指针(PSP)的作用
  • 每个任务的栈(由 PSP 指向)是 “上下文仓库”,保存了任务暂停时的所有寄存器状态和运行位置(PC 值)。
  • 上下文切换的本质是 “PSP 的切换”:从当前任务的 PSP 切换到新任务的 PSP,让 CPU 认为 “新任务一直在运行”。

调度器不会 “一直运行”,而是在特定时机被触发,主要包括:

  1. 定时中断(系统滴答定时器,SysTick)

    • RTOS 的 “心跳”(如每 1ms 触发一次),用于任务延时管理(vTaskDelay())和时间片轮转。
    • 中断中会检查 “是否有任务延时到期” 或 “时间片用完”,若需要切换则触发调度。
  2. 任务主动放弃 CPU(调用vTaskDelay()xSemaphoreTake())

  3. 高优先级任务就绪

  4. 任务优先级动态变化

RTOS的启动流程

单片机上电之后,内核复位,获取MSP的值(获取PC值);复位中断函数;启动文件:初始化MSP,初始化PC(栈顶指针),设置堆栈大小;初始化中断向量表,调用_main函数;main函数种先执行相应的硬件初始化然后调用OS初始化函数进行rtos系统初始化;接着创建开始任务,完成后,调用多任务调度函数,启动多任务函数,开始运行(优先级/时间片)进行

为什么要用RTOS

RTOS是为了管理多任务执行,提高系统的实时性和稳定性;相较于裸机开发,RTOS的核心在于CPU资源的调度,把任务拆解多个独立模块,看起来并发运行;当某一个任务卡住时整个系统不至瘫痪。

互斥量优先级翻转优先级继承

优先级翻转

高优先级任务H低优先级任务L通过 信号量机制,共享资源。目前低优先级任务L占有资源,锁定了信号量,高优先级任务 H运行后将被阻塞,直到低优先级任务 L释放信号量后,Task H才能够退出阻塞状态继续运行。但是高优先级任务 H在等待低优先级 L释放信号量的过程中,中等优先级任务M抢占低优先级任务L,从而延迟了信号量的释放时间,导致高优先级 H阻塞了更长时 间,这种现象称为优先级倒置或优先级反转(翻转)。

优先级继承:

当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任 务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务 会将低优先级任务的优先级提升到与自己相同的优先级。

http://www.dtcms.com/a/473380.html

相关文章:

  • 数据结构实战:顺序表全解析 - 从零实现到性能分析
  • 【C++进阶】继承上 概念及其定义 赋值兼容转换 子类默认成员函数的详解分析
  • 华为matebook16s 2022禁用触摸板和触摸屏操作
  • GridRow 和 Column 有啥区别
  • 030159网站建设与维护中国科技成就素材
  • Echarts 5.6.0 Grid 坐标系中 Y 轴可视化的优化之路
  • Java 线程池如何知道一个线程的任务已经执行完成
  • JVM字节码与类的加载(一):类的加载过程详解
  • 强军网网站建设网站需要备案才能建设吗
  • 耄大厨——AI厨师智能体(3-工具调用)
  • (二)黑马React(导航/账单项目)
  • SA-LSTM
  • 【Java并发】深入理解synchronized
  • Docker 安装 Harbor 教程
  • Python+Flask+Prophet 汽车之家二手车系统 逻辑回归 二手车推荐系统 机器学习(逻辑回归+Echarts 源码+文档)✅
  • AI_NovelGenerator:自动化长篇小说AI生成工具
  • 济南网站制作开通免费个人简历模板官网
  • 全链路智能运维中的异常检测与根因定位技术
  • 解构 CodexField:创作者经济到模型金融化的代币逻辑与潜力
  • SpringBoot 实现自动数据变更追踪
  • C语言⽂件操作讲解(3)
  • 对网站做数据分析北京市建设工程信息
  • 1.6虚拟机
  • XCP服务
  • Excel - Excel 列出一列中所有不重复数据
  • 如何获取用户右击的Excel单元格位置
  • 昆明企业网站建设公司虹口建设机械网站制作
  • 宁波p2p网站建设黑龙江省建设安全网站
  • Spring Boot 3零基础教程,自动配置机制,笔记07
  • Spring通关笔记:从“Hello Bean”到循环依赖的奇幻漂流