1. ARM Cortex-M 架构精讲:寄存器模型、异常处理与中断向量表、存储器映射与MPU、总线架构与流水线
各位同学,咱们今天正式开讲。ARM Cortex-M 系列,说白了就是嵌入式领域的“心脏”。我做了十几年低功耗嵌入式开发,从 M0 到 M7 都用过,每次看手册都能发现新东西。这一章咱们把底层的几个硬核概念掰开揉碎,讲清楚。
1.1 寄存器模型:程序员的第一视角
Cortex-M 的寄存器模型,比老大哥 ARM7/9 简单太多了。它没有 Banked 寄存器,也没有 CPSR 那种复杂的状态位。你想想看,这对于 RTOS 的上下文切换来说,简直是福音。
核心寄存器就这些:
| 寄存器组 | 寄存器名 | 用途简述 |
|---|---|---|
| 通用寄存器 | R0-R12 | 数据操作、函数参数传递 |
| 堆栈指针 | SP (R13) | MSP(主栈)/ PSP(进程栈) |
| 链接寄存器 | LR (R14) | 函数返回地址 |
| 程序计数器 | PC (R15) | 当前指令地址 |
| 特殊寄存器 | xPSR | 程序状态字(标志位、异常号) |
| 特殊寄存器 | PRIMASK / FAULTMASK / BASEPRI | 中断屏蔽控制 |
| 特殊寄存器 | CONTROL | 特权级、栈指针选择 |
这里有个关键点:R13 到底指向哪个栈? 由 CONTROL 寄存器的 bit[1] 决定。0 用 MSP,1 用 PSP。中断来了,硬件自动切回 MSP,你不用担心。
1.2 异常处理与中断向量表:硬件自动化的艺术
Cortex-M 的异常处理,是我见过最优雅的设计之一。它把中断和异常统一管理,从 #1 复位到 #15 系统异常,再到 #16 以后的外设中断,全部放在一张向量表里。
这张表放在哪里?默认在 0x00000000。但你可以通过 SCB->VTOR 寄存器重映射。我在做 Bootloader 时,就经常把向量表搬到 RAM 里,方便动态修改。
异常优先级是这样的:
- 复位 (-3): 最高,不可屏蔽
- NMI (-2): 不可屏蔽中断
- HardFault (-1): 最后的兜底
- SVCall / PendSV / SysTick: 可配置优先级,RTOS 的命根子
- 外设中断 (0-255): 优先级可编程
1.3 存储器映射与 MPU:给内存上把锁
Cortex-M 的 4GB 地址空间,被划分成几个固定的区域。我画个图你就明白了:
MPU 这东西,说白了就是给内存上锁。你可以在 RTOS 里给每个任务分配独立的 MPU 区域,任务 A 访问不了任务 B 的栈。这在安全关键系统里是标配。
1.4 总线架构与流水线:性能的隐形推手
Cortex-M 的总线架构,是哈佛结构的变种。指令总线和数据总线分开,可以同时取指和访存。M3/M4 还有独立的系统总线,用来访问外设。
流水线方面,M0/M0+ 是 2 级流水线(取指 + 执行),M3/M4 是 3 级流水线(取指 + 译码 + 执行),M7 更夸张,6 级超标量。流水线越深,频率越高,但分支预测失败的代价也越大。
| 内核 | 流水线级数 | 总线架构 | 典型频率 | 低功耗特性 |
|---|---|---|---|---|
| Cortex-M0+ | 2 级 | 单总线 (von Neumann) | ~48 MHz | 极低功耗,适合电池设备 |
| Cortex-M3 | 3 级 | 哈佛 (I-Code + D-Code + System) | ~120 MHz | 平衡功耗与性能 |
| Cortex-M4 | 3 级 | 哈佛 + DSP/SIMD | ~200 MHz | 带 FPU,适合信号处理 |
| Cortex-M7 | 6 级 | 哈佛 + 双发射 + 缓存 | ~400 MHz | 高性能,功耗较高 |
总线架构还有个细节:位带操作 (Bit-Banding)。M3/M4 在 SRAM 和外设区各有一个 1MB 的位带别名区。你往别名区写一个字,硬件自动转换成对目标地址的位操作。这在操作 GPIO 输出寄存器时特别有用,不用读-改-写,直接写位就行。
好了,这一章的内容就到这里。寄存器模型、异常向量表、MPU 保护、总线流水线,这些是 Cortex-M 的骨架。后面咱们讲 RTOS 移植和驱动开发,全得靠这些底子。你先把这些概念消化掉,后面就顺了。