STM32内核细讲《从CPU架构到操作系统实现》

📅 2026/8/8 10:39:23
STM32内核细讲《从CPU架构到操作系统实现》
1.1 概述章-CPU架构99%的手机50%的CPU都是基于ARM的。只卖架构知识产权IP里面有Cortex-A手机常用Cortex-R用的少Cortex-M低功耗内核架构设计指令集指令集ISA就是 CPU 能懂的全部单词的集合——软件用这些单词写程序CPU 按这些单词干活Cortex-M是Thumb指令集在上面跑ARM指令集会出问题。Thumb 是 ARM 指令集的压缩版——每条指令从 32 位缩到 16 位牺牲了部分功能但大幅节省 Flash 空间。Thumb-2 又加回了 32 位指令形成了现在的 16/32 位混合模式。STM32F103这次不讲外设的应用讲内核操作系统应用。M3核移植到M7核是省事的高版本兼容低版本2.1 编译章 编译工具链以前我们都是通过集成开发环境IDE进行一键编译会忽略很多细节。编译工具链常见ARM公司自研发的keil5收费GCCGNUSTM公司的cubeMXGNU 编译器套件你把 C 代码丢给它它产出机器码。C语言编译器有一个也叫gcc注意区分STM32CubeIDE叫集成开发环境是GCC编译工具链将.c文件转换成机器码可执行文件cubeMX生成.c文件2.2 写一段最简单的程序先创建.sGCC文件。去模拟int a1;语句的汇编汇编效率最高和CPU直接对话为什么不用汇编语言可移植性封装性都不如高级语言根据汇编手册去对照编译出.o文件二进制中间文件通过链接过后的才是可执行文件通过hex转换成.hex文件可以更清晰看见可执行文件的结果。烧录把编译好的机器码二进制数据写到CPU存储器中。方式USB蓝牙WIFI后2者是无线通讯方式专业术语叫OTA升级2.3 反汇编图增加了一些细节反汇编逆向的过程把已经转换的机器码转换为汇编代码。.s到.o文件是把汇编代码转为机器码。反汇编作用将商品的机器码获取出来然后反汇编为汇编代码可以看见主要的算法逻辑工具反汇编器(有命令)将.bin文件转成.s。.hex也可反汇编 .o以及.elf都可以反汇编.elf 是裸机/Linux 的可执行文件.exe 是 Windows 的可执行文件不可写进MCU。高级语言.c到.s汇编文件但是可以将汇编代码转为C语言吗不是很好的效果。启动流程我们写的程序是怎么开始执行的呢STM32怎么启动的程序计数器PC从中断向量表的第二项获取初始值初始化中断向量表初始化堆栈指针 MSPPC程序计数器PC 寄存器里永远存着下一条即将被 CPU 取指执行的指令的内存地址。从0地址处启动伪代码GNU 伪操作是你写在.s文件里让汇编器执行的命令GNU 伪操作 以.开头的指令不是给 CPU 看的是给汇编器看的。STM32启动原理芯片用户可以根据实际需求来选择启动方式通过映射到0地址处。ARM公司只是提供了从0地址处开始启动STM32Id链接脚本链接脚本 告诉链接器「哪个节区往哪放」的地图CPU寄存器寄存器CPU内部存储器CPU外部存储器比寄存器慢4个指令周期左右SMP多核处理器一个核就有一组寄存器R13SP堆栈指针R14LR链接寄存器R15PC程序计数寄存器R0-R12通用寄存器一般自己写寄存器汇编代码都是在基础寄存器上面写因为一些指令无法在特殊寄存器上面生效我们的汇编指令叫GNU另一个对比就是ARM汇编指令PC寄存器R15CPU执行程序的本质就是靠PC寄存器不断的更新更新频率由时钟决定SP堆栈指针寄存器R13堆栈指针 SP 就是 CPU 用来记当前栈顶在哪的寄存器——PUSH 时它递减POP 时它递增始终指向栈上最新存的数据push递减是因为是向下计数POP取读数据LR链接寄存器R14CPU 自动帮你记这个函数执行完了跳回哪的专用寄存器。还有一个重要作用记录异常返回值存储系统嵌入式编程的本质右边不是CPU存储系统是存储器介质设备通过通讯外设进行与CPU连接嵌入式编程的本质嵌入式编程本质上就是在操作存储器地址空间单元。每一条 C 语句最终都溯源到汇编所以 STM32 编程 查手册找地址 → 往地址写值 → 硬件就按你的设定工作。 HAL 库只是把这一层封装了让你不用记地址。读写存储器i和i谁的效率高没有编译优化下不一定有加编译优化下一般是等效率的电压钳位电路把I/O输入控制在VDD和VSS之间大于VDD上面就导通小于VSS下面就导通想中间过去只能满足在VDD和VSS之间。嵌入式编程就是在读写存储器中断的本质抢占型调度机制程序崩溃的本质程序崩溃的本质 CPU 执行了它无法理解的指令或访问了不该碰的地址触发了硬件级的异常捕获机制高阶调试专题int a1;其中a放在内存左值可读可写掉电丢失1右值只能读放在flash中掉电不丢失内存控制器是厂家定义的CPU里面有专门做计算的ALU计算电路模块寄存器叫存储电路模块韦东山调试专题在Keil5里面点击调试会自动帮我们下载好程序故需要先进行连接板子ST-Link 核心价值是 下载 调试其中调试断点/单步/看变量是它的不可替代价值——串口下载做不到。走SWD调试。Debug模式必须要连接ST-LinkCtrlB可以去掉所有断点也可以选择在断点处运行多少次Step Out步出快捷键 ShiftF8作用如果你已经进入了某个函数内部按这个按钮会一次性执行完当前函数剩下的所有代码然后自动跳回到 “调用这个函数的那一行” 的下一行。比如你不小心按 F7 进到了 HAL 库的长函数里或者你看完了函数前半段逻辑确认没问题想快速退回到主循环里就按 ShiftF8 直接跳出当前函数ARM架构volatile主要是优化作用编译器看你没用这个变量或者函数就会优化掉变成一个空函数。导致一些问题SP 的值是一个内存地址而这个地址处存的是栈顶数据。地址处我们去查找RAM对应的存储单元第一条变了就乱套了后续程序都出错第二条那么其他寄存器由谁来保证不变呢上张截图是从LR寄存器的二进制位数得到Cortex-M3 内核没有 FPU不支持硬浮点栈存在RAM里面。寄存器里存的是32 位的值4字节——可能是数字、地址、字符、状态标志CPU 不关心它是什么类型代码说它是啥就是啥。STMFD 一次把多个寄存器按顺序压进栈类似于PUSH举例STMFD SP!, {R4-R11, LR}顺序编号小的寄存器存低地址LR 被压进栈里备用!SP 压完更新 SP关于无调式器打印出来的东西自己创建一个内存空间做打印栈然后自己写汇编代码让软件存入其他寄存器相比栈帧的寄存器怎么知道我们程序崩溃呢调试全速运行然后跳转到handle函数首先看PC地址如果搜素不到或者乱七八糟就看LR寄存器的值就找到崩溃在哪个函数里面疑似LR判断条件core 文件 程序死机瞬间的现场快照把崩溃那一刻的寄存器、栈、内存全部存下来事后离线分析。GDB又是啥GDB 和 Keil 调试是同一个东西的两个形态GDB GNU DebuggerLinux 世界的Keil 调试器——只是它没有图形界面全靠敲命令。你学的东西它全能干还多一个绝活离线分析 core 文件。C语言