RTOS篇——CortexM内核与RTOS的关联
本文最后更新于72 天前,其中的信息可能已经过时,如有错误请发送邮件到527388734@qq.com

一、引言

在上一篇文章中,我们完成了FreeRTOS的源码移植,迈出了RTOS实践的第一步。那么从这一篇文章开始,我们将真正进入RTOS的深层世界——从他的内核支持角度去刨析RTOS是如何完成多任务的一个调度机制。

很多初学者在学习RTOS时,往往停留在API调用的层面——知道如何创建任务、如何使用延时,却对”任务究竟是如何切换的”这个问题感到困惑。实际上,现代RTOS的高效运行,很大程度上得益于Cortex-M内核提供的硬件级支持。

好了,我们话不多说,我们开始一步一步探索CortexM内核的奥妙。

二、何为CortexM内核

在开始CortexM内核介绍之前,需要先为大家建立起对于CortexM内核的感性认知。电脑想必大家一定都很熟悉,无论是台式机还是笔记本,它们的核心部件被称为CPU,比如Intel的酷睿i5、i7,或者AMD的锐龙系列。CPU的主要职责就是执行所有程序指令,相当于就是电脑的“大脑”。

那么,回到我们嵌入式微控制器领域,STM32单片机的“大脑”是什么呢?

答案就是CortexM内核!

如果把STM32比作成一台电脑

  • Cortex-M内核 就相当于这台电脑的 CPU——负责执行指令、进行运算。
  • STM32 则相当于一整个 主板——它不仅包含了这个CPU,还集成了内存(SRAM)、闪存(Flash)、以及各种外设(定时器、ADC、通信接口等)

更准确的说,CortexM内核是ARM公司设计的一个处理器核心,而STM32是意法半导体公司基于这个核心,加上自己的内存和外设,最终制造出来的完整芯片。

理清这层关系后,我们就能理解一个重要事实:RTOS的本质,就是通过配置和操作Cortex-M内核的各种寄存器,来实现多任务的调度与管理。无论是任务的创建、切换,还是中断的管理,最终都会落实到对内核寄存器的操作上。

三、CortexM内核关键寄存器

3.1 何为寄存器

简单来说寄存器就是CPU内部的一个高速存储单元,他们就像是CPU的工作台,运算和控制都需要通过寄存器来完成。比如要计算a + b的结果,CPU需要先把a和b从内存搬到寄存器里,在寄存器中完成加法运算,再把结果存回内存。因此,我们在接触内核,了解他的关键寄存器是很关键的。

3.2 关键寄存器分类

3.2.1 内核寄存器

内核寄存器指的是R0~R15这些寄存器,他们之间可以再次进行细分为通用寄存器组(R0-R12)和特殊功能寄存器组(R13~R15)

① 通用寄存器:

存放运算数据和临时变量。在RTOS中,由于涉及到大量的任务切换,为了保证切换过程中数据不丢失,必须对这些寄存器进行保存和恢复——这正是通用寄存器的职责所在。

其实不仅在RTOS中,裸机环境下的普通函数调用也需要通用寄存器的参与。根据ARM的AAPCS调用标准(ARM体系结构过程调用标准):

  • R0-R3:用于传递函数参数和返回值
  • R4-R11:在函数调用过程中需要保持其值不变
int add(int a,int b){
   return a+b; // 运算结果通过R0返回
}
int main(){
  add(1,2); // 参数1和2分别存入R0、R1
  return 0;
}

当执行add(1, 2)时,CPU会按照AAPCS规则自动完成以下操作:

  1. 将参数12分别存入寄存器R0R1
  2. 跳转到add函数执行加法运算
  3. 将运算结果存入R0中返回
  4. 主函数从R0取出结果,完成调用

这就是最基础的寄存器传参机制。而在RTOS中,任务切换时保存的不只是R0-R3,而是所有可能被任务使用的通用寄存器(R0-R12),确保任务恢复运行时现场完全复原。

② 特殊功能寄存器组(R13~R15)
R13——栈指针SP

这个寄存器指向了栈顶的位置,保存了栈的最新”水位线”,而栈是存储程序运行时所产生的临时变量,可以说有了这个寄存器的记录,就一定程度规避了数据踩踏。

 Cortex-M内核拥有两个栈指针——MSP(主栈指针)和PSP(进程栈指针)。

他在RTOS中的作用:

  • PSP:当前正在运行的任务使用它,每个任务都有自己的独立栈空间
  • MSP:内核和中断服务程序使用它,实现内核与任务的隔离
  • 任务切换时: 通过读取PSP就能找到当前任务的栈顶,从而保存/恢复上下文
R14——链接寄存器LR

记录函数调用结束后应该返回到哪里

当异常发生时,LR会被赋予一个特殊值——EXC_RETURN

他在RTOS中的作用:

  • 异常返回时,CPU通过解析EXC_RETURN就知道:返回后使用MSP还是PSP?
  • 正是这个机制,让RTOS能够实现”中断中切任务”的神奇操作
R15——程序计数器PC

这个寄存器非常关键:PC指向哪段程序,CPU就执行哪段程序。它和LR寄存器配合实现了程序的”跳转”功能——当需要跳转到子程序时,LR会记录下返回地址;子程序执行完毕后,再将LR的值赋给PC,就能精准地跳转回原先的位置。

他在RTOS中的作用:

  • 任务切换的本质,就是把PC的值修改为新任务的入口地址
  • 当从PendSV异常返回时,CPU自动将新任务的PC值加载进来,新任务随即开始运行

3.2.2 状态寄存器——xPSR

在介绍状态寄存器之前,我们需要先厘清Cortex-M内核的状态、模式与访问权限这三个重要概念。

①运行状态

  • Thumb状态:执行Thumb/Thumb-2指令集的正常运行状态
  • 调试状态:当内核暂停执行(如断点触发)时进入的状态

②工作模式

  • 线程模式(Thread Mode):通常用于运行用户任务
  • 处理者模式(Handler Mode):用于运行中断服务程序和异常处理

③ 访问权限

  • 特权访问:可以访问所有寄存器、内存和指令,内核和中断运行在此级别
  • 非特权访问:部分资源受限,用于运行用户任务,实现系统保护

RTOS正是利用这些硬件级别的隔离机制,实现内核与任务的分离保护——用户任务运行在线程模式+非特权级+PSP,而内核运行在处理者模式+特权级+MSP,确保任务出错时不会拖垮整个系统。

下面这个图展示了xPSR每一个位标识的具体那个状态:

  • 31~27 :标识着程序运算状态的状态标识,比如运算1-2为负数,那么第31位就置位,我们可以通过判断相应标识位的状态来进行程序的不同分支选择。
  • 26~25 15~10 :是中断继续指令,我们不需要过多关心。
  • 24:标识着当前内核所处在的状态,当置位为1标识着当前为Thumb状态,反之则为调试状态。
  • 19~16 :我们同样可以不用过多关心。
  • 8~0:标识当前正在处理的中断或异常例如:0表示无异常,11表示SVCall,14表示PendSV…

3.2.3 中断屏蔽寄存器

总结来说中断屏蔽寄存器就是根据中断向量表的一个编号来规划哪些中断需要响应,哪些不需要。

3.2.4 控制寄存器——CONTROL

CONTROL寄存器只能在特权访问等级进行修改(即只能在异常情况下进行CONTROL的修改),而读取在特权和非特权下都可以。

下图是CONTROL寄存器的每一位:

  • bit0:定义线程模式中的特权等级
    • 当该位为0时(默认),处理器会处于线程模式中的特权等级
    • 当该位为1时,则处于线程模式的非特权等级
  • bit1:定义栈指针的选择
    • 当该位为0时(默认),线程模式使用主栈指针(MSP)
    • 当该位为1时,线程模式使用进程栈指针(PSP)
  • bit2:浮点单元控制,可不做过多关注

四、AAPCS仿真验证

4.1 环境准备

在仿真验证前,需要先创建一个KEIL的空工程,如下图:

4.2 仿真验证

仿真界面介绍:

大家可以用下面这个例子进行仿真验证:

#include <stdio.h>
#include "stm32f4xx.h"

int add(int a,int b,int c,int d)
{
    return a+b+c+d;

}

int main(){
	
	add(0x11111111,0x22222222,0x33333333,0x44444444);
	while(1);
	return 0;
}

开始进入到仿真模式:

五、小结

至此,我们初步感受了通用寄存器参与简单运算的过程。这个仿真环境在后面搭建RTOS时会经常用到,本篇博客先带大家熟悉一下仿真环境,以及寄存器的基本调用机制。后续文章我们将逐步深入探究RTOS与寄存器之间的紧密联系,敬请期待!

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇