ARM Cortex-M 架构:从处理器家族到异常处理

ARM Cortex-M 系列,说白了就是嵌入式世界里的「瑞士军刀」。我最早接触 ARM 是在大学实验室,那时候还是 ARM7TDMI,烧程序得用并口线。后来转到 Cortex-M,第一感觉就是——这玩意儿太友好了。你想想看,一个 32 位处理器,功耗能控制在毫瓦级,中断响应还快得离谱,这不就是为嵌入式量身定做的吗?

ARM 处理器家族:一张图看懂

ARM 处理器分三大类:Cortex-A、Cortex-R、Cortex-M。名字好记——A 是 Application(应用),R 是 Real-time(实时),M 是 Microcontroller(微控制器)。

系列 典型场景 我见过的坑
Cortex-A 手机、平板、Linux 系统 跑 Linux 没问题,但裸机开发?别自找麻烦
Cortex-R 硬盘控制器、汽车刹车 硬实时要求高,但开发工具贵
Cortex-M 传感器、电机控制、IoT 设备 入门简单,但中断优先级设错会死机

我个人习惯是:做消费电子用 M4 或 M7,做低功耗电池设备用 M0+。选型选对了,后面少走一半弯路。

Cortex-M 系列特点:为什么它这么火?

Cortex-M 有几个硬核特点,我一个个说。

  • Thumb-2 指令集:16 位和 32 位指令混用。代码密度高,性能也不差。我在一个 Flash 只有 64KB 的项目里,靠 Thumb-2 硬是把功能塞进去了。
  • 嵌套向量中断控制器(NVIC):中断优先级可配置,支持抢占。嗯,这里要注意——优先级分组搞错了,低优先级中断可能永远得不到响应。
  • 低功耗模式:Sleep、Deep Sleep、Standby。我做过一个温湿度采集器,用 Deep Sleep 模式,两节 AA 电池撑了半年。
  • 系统节拍定时器(SysTick):专为 OS 设计的 24 位递减定时器。跑 RTOS 必备,裸机也能当精准延时用。

核心优势:Cortex-M 把「高性能」和「低功耗」这对矛盾体,硬是揉在了一起。你想想看,一个跑 200MHz 的 M7,功耗才几十毫瓦,这在十年前根本不敢想。

寄存器组:程序员最该记住的 16 个寄存器

Cortex-M 的寄存器组,说白了就是 R0-R15 加上特殊功能寄存器。我刚开始学的时候,总觉得寄存器太多记不住。后来发现,常用的就那几个。

寄存器 别名 用途 我的经验
R0-R12 通用寄存器 数据运算、地址暂存 R0-R3 传参数,R4-R11 保存局部变量
R13 SP(堆栈指针) 指向当前堆栈 MSP 和 PSP 切换时容易出错,我吃过亏
R14 LR(链接寄存器) 保存函数返回地址 中断里改 LR 要小心,否则回不来
R15 PC(程序计数器) 指向当前指令 PC 最低位必须是 1(Thumb 模式)
xPSR 程序状态寄存器 标志位、中断状态 调试时多看 xPSR,能发现很多问题

小技巧:调试时用 IDE 的寄存器窗口,盯着 SP 和 PC 看。程序跑飞了,先看 PC 是不是指向了非法地址。我曾经花了两小时查一个 bug,最后发现是堆栈溢出把 PC 给覆盖了。

工作模式:线程模式 vs 处理模式

Cortex-M 只有两种工作模式,比传统 ARM 简单多了。

  • 线程模式(Thread Mode):跑普通代码。可以运行在特权级或用户级。
  • 处理模式(Handler Mode):跑异常处理程序。始终在特权级。

为什么会这样设计?说白了,就是为了安全。你想想看,如果用户代码能随便改中断向量表,那系统还怎么稳定?

我记得有个项目,同事把系统时钟配置放在了线程模式的用户级代码里,结果一运行就 HardFault。查了半天才发现,是权限不够。后来我把时钟初始化放到启动代码里,问题就解决了。

异常处理:中断系统的灵魂

Cortex-M 的异常处理,是我最喜欢的部分。它把中断响应时间压缩到了极致。

异常类型

异常编号 名称 优先级 触发条件
1 Reset -3(最高) 上电或复位
2 NMI -2 不可屏蔽中断
3 HardFault -1 任何错误
4-10 系统异常 可配置 MemManage、BusFault 等
11-15 保留 - -
16+ 外部中断 可配置 外设触发

避坑指南:我曾经把两个中断的优先级设成了相同值,结果一个中断没处理完,另一个又来了,导致堆栈溢出。记住——同优先级中断不会互相抢占,但会排队。如果处理时间太长,后面的中断可能会丢。

中断响应流程

Cortex-M 的中断响应,硬件自动完成了大部分工作。流程是这样的:

  1. CPU 检测到中断请求
  2. 硬件自动压栈:PC、LR、xPSR、R0-R3、R12
  3. 从向量表取出中断服务函数地址
  4. 切换到处理模式,执行 ISR
  5. ISR 执行完毕,硬件自动出栈
  6. 返回线程模式,继续执行

整个过程只需要 12 个时钟周期。我测过 M4 的中断延迟,从触发到进入 ISR,大概 80ns(以 168MHz 计)。这个速度,做电机控制绰绰有余。

知识体系总览

下面这张图,把本章的核心知识点串起来了。我建议你保存下来,复习时看一眼就全想起来了。

ARM Cortex-M 架构知识体系 ARM Cortex-M 架构知识体系 Cortex-M 架构 处理器家族 Cortex-A / R / M 寄存器组 R0-R15 / xPSR / SP 工作模式 线程 / 处理模式 异常处理 NVIC / 中断响应 核心特点:Thumb-2 指令集、NVIC、低功耗、SysTick 异常响应仅需 12 个时钟周期,硬件自动压栈/出栈 Thumb-2 指令集 NVIC 中断控制器 低功耗模式 选型建议 M0+:低功耗传感器 | M4:电机控制、音频 | M7:高性能计算、AI 推理

写在最后

ARM Cortex-M 架构,说复杂也复杂,说简单也简单。你只要抓住三个核心:寄存器怎么用、模式怎么切、中断怎么处理。剩下的,都是在这些基础上堆功能。

我个人建议,初学者先拿一块 M4 开发板,点个灯,然后写个定时器中断。等你能让 LED 以精确的 1 秒间隔闪烁时,恭喜你——你已经掌握了 Cortex-M 的精髓。