Cortex-M3 内核

1. 概述

ARM Cortex-M3 是一款专为微控制器领域设计的 32 位处理器内核,由 ARM 公司开发。它采用 哈佛架构(指令总线与数据总线分离),支持 Thumb-2 指令集,在代码密度与性能之间取得了良好平衡。Cortex-M3 内核集成了 嵌套向量中断控制器(NVIC),提供确定性的中断处理能力,使其成为汽车电子、工业控制和物联网等嵌入式应用的理想选择。

Cortex-M3 内核的主要特点包括:

  • 32 位处理器内核,采用 Harvard 架构
  • Thumb-2 指令集,提供 16 位和 32 位混合编码
  • 内置嵌套向量中断控制器(NVIC)
  • 支持 1 到 240 个物理中断
  • 可配置的 8 或 16 个优先级位
  • 硬件自动保存和恢复上下文
  • 支持咬尾中断和晚到中断机制

2. 操作模式与特权级别

Cortex-M3 处理器通过 操作模式(Operating Mode)特权级别(Privilege Level) 两个维度来构建其运行模型。这种设计允许嵌入式系统在裸机或 RTOS 环境下实现基础的访问权限管理和内核-用户态隔离。

2.1 操作模式

处理器在任何时刻都处于以下两种模式之一:

模式 名称 说明
线程模式(Thread Mode) 常规应用模式 处理器在复位后即进入此模式,用于执行常规的应用软件。
处理者模式(Handler Mode) 异常处理模式 当处理器响应异常或中断时,会自动进入此模式。所有异常服务例程(ISR)均在此模式下运行。

2.2 特权级别

处理器定义了两种特权级别,用于控制对特定寄存器、内存区域及系统资源的访问权限:

级别 名称 说明
特权级(Privileged) 全访问级别 软件可以访问所有的处理器资源和内存区域。复位后的默认状态为特权级
用户级(Unprivileged) 受限访问级别 受限模式,软件禁止访问系统控制空间(如 NVIC、MPU 配置寄存器),且不能执行某些特权指令(如 CPSMSR 访问系统控制寄存器)。这种限制可有效提高系统的健壮性。

2.3 模式与级别的组合关系

操作模式与特权级别的组合,以及堆栈指针(SP)的选择,遵循以下规则:

操作模式 软件执行状态 特权级别 使用的堆栈指针
线程模式 常规应用程序 特权级 或 用户级(可配置) 主堆栈指针(MSP)或 进程堆栈指针(PSP)
处理者模式 中断/异常服务例程 始终为特权级 主堆栈指针(MSP)

关键规则

  1. 异常响应:当异常发生时,处理器硬件会强制将模式切换至处理者模式,并自动切换到特权级,始终使用 MSP
  2. 模式切换:用户级代码可以通过执行 SVC(服务调用) 指令触发系统调用,来请求将模式切换回特权模式。

2.4 双堆栈机制

Cortex-M3 支持两个物理堆栈指针,以实现内核代码与用户应用代码的堆栈隔离:

堆栈指针 全称 用途
MSP 主堆栈指针 处理者模式使用;线程模式下的特权级代码也可使用。复位后默认使用。
PSP 进程堆栈指针 仅用于线程模式。在 RTOS 中,通常配置为线程模式下使用 PSP,每个任务拥有独立的堆栈。

CONTROL 寄存器控制当前使用的堆栈指针:

CONTROL[1] (SPSEL) 线程模式使用 处理者模式使用
0 MSP MSP
1 PSP MSP(强制)

Note:当进入中断服务函数时,硬件会自动切换回 MSP,从而实现任务的堆栈隔离,防止应用程序错误破坏内核栈。


3. 中断系统的具体行为

Cortex-M3 的中断系统是其核心竞争力之一,基于 嵌套向量中断控制器(NVIC) 实现,具备高性能和确定性的特点。

3.1 NVIC 核心特性

特性 说明
嵌套中断支持 高优先级中断可以抢占低优先级中断,硬件自动处理优先级逻辑。
向量化处理 NVIC 包含一个向量表,当特定中断触发时,硬件会自动定位并跳转到对应的 ISR。
动态优先级配置 支持可编程的中断优先级(8 或 16 个优先级位),允许用户在运行时调整。
中断屏蔽 提供 PRIMASK、FAULTMASK、BASEPRI 等屏蔽寄存器,允许暂时屏蔽特定中断。

3.2 中断触发与状态管理

Cortex-M3 支持两种类型的中断信号:

触发类型 说明 处理机制
电平敏感 中断线保持有效电平,直到被服务 NVIC 锁存中断;ISR 必须清除外设的中断源;若退出 ISR 后信号仍保持,中断会立即重新触发。
脉冲触发 检测到时钟上升沿或指定宽度的脉冲 NVIC 在时钟上升沿采样并锁存。进入 ISR 时,硬件自动清除挂起状态。
中断状态

每个中断有三种状态:

状态 说明
未激活 中断未被触发,或已处理完成。
挂起 中断已触发,等待 CPU 响应。
激活 CPU 正在执行该中断的服务例程。
中断的硬件与软件控制

中断的挂起状态可以由硬件或软件触发:

  • 硬件触发:外设将中断线置为有效电平或产生脉冲。
  • 软件触发:通过向 NVIC 的 中断设置挂起寄存器软件触发中断寄存器(STIR) 写入相应位,可以在软件中强制产生一个中断。

3.3 中断优先级与抢占

Cortex-M3 使用 PRIGROUP 字段将优先级寄存器拆分为抢占优先级子优先级

PRIGROUP 抢占优先级位 子优先级位
0 7:1 (7 bits) 0 (1 bit)
7 7 (1 bit) 6:0 (7 bits)

抢占规则

  • 更高抢占优先级的中断可以抢占当前中断。
  • 相同抢占优先级下,子优先级不影响抢占(仅用于同优先级下的排队)。
  • 相同抢占优先级的中断遵循编号越小优先级越高的默认规则。

3.4 高级中断处理机制

为提高中断响应的实时性并减少不必要的压栈/出栈操作,Cortex-M3 引入两项硬件优化:

机制 说明 优势
咬尾中断 当处理器即将退出一个 ISR 时,如果检测到有另一个挂起的中断,它将跳过出栈和入栈过程,直接进入新的 ISR。 通常可将连续中断处理的延迟缩短至 6 个时钟周期,显著提高效率。
晚到中断 在当前中断的入栈阶段,如果检测到更高优先级的中断,处理器将优先处理高优先级的晚到中断。 优先响应紧急事件,且无需为高优先级中断重做入栈操作。

3.5 中断响应序列:硬件自动处理流程

当 NVIC 确认一个优先级足够的中断被挂起后,处理器硬件会自动执行一个完整的"中断响应序列",无需任何软件干预。这个过程主要包括三个核心步骤:入栈取向量寄存器更新

3.5.1 入栈

入栈是处理器自动保存当前程序现场的过程,目的是确保 ISR 执行完毕后,被中断的线程能够正确恢复并继续执行。

  • 入栈时机:在确认响应中断后,取向量开始之前。
  • 入栈内容:处理器硬件会将 8 个 32 位寄存器 按照固定顺序自动压入当前活动的堆栈

入栈的8个寄存器:

寄存器 名称 说明
PC 程序计数器 被中断指令的下一条指令地址。
xPSR 程序状态寄存器 包含 ALU 标志(N、Z、C、V)、Thumb 状态位等。
R0-R3 通用寄存器 R0-R3 用于参数传递和临时存储。
R12 内部调用临时寄存器 用作暂存器。
LR 链接寄存器 异常返回时装载 EXC_RETURN 值。

关键点

  • 为什么是这8个寄存器?AAPCS 调用约定规定 R0-R3、R12 和 LR 可能被函数修改,而 R4-R11 需由被调用者保存。硬件只自动保存可能被修改的寄存器,其余寄存器由编译器在函数开头生成的代码负责压栈。
  • 使用的堆栈指针:在处理者模式下,始终使用 MSP。若在线程模式下配置为使用 PSP 发生异常,硬件会在入栈前将 SP 由 PSP 自动切换到 MSP。

入栈后堆栈布局(8 words = 32 字节):

text

     高地址
         +-------------------+
         |       PC          |
         |     xPSR          |
         |       R12         |
         |       R3          |
         |       R2          |
         |       R1          |
         |       R0          |
         |       LR          |
         +-------------------+  ← 当前 SP (MSP) 指向这里
     低地址
3.5.2 取向量

入栈完成后,处理器需要知道要执行哪个 ISR 的地址。

  • 向量表:位于内存中的一个表(起始地址由 VTOR 寄存器配置,复位时通常位于 Flash 起始地址 0x00000000)。
  • 向量表条目:每个异常/中断对应一个表项,每个表项为 4 字节,存储对应 ISR 的入口地址
  • 映射关系
    • 异常编号 1~15 为系统异常(复位、NMI、硬故障等)。
    • 异常编号 ≥16 为外部中断,对应芯片厂商定义的外设中断。
  • 取向量计算:硬件将 (异常编号 << 2) 作为向量表内的偏移量,读取该地址中的 32 位值,作为 PC 加载值
3.5.3 寄存器更新

取向量后,处理器硬件会更新一系列关键寄存器:

寄存器 更新值 说明
PC 从向量表中读取的 ISR 入口地址 处理器跳转至 ISR 的第一条指令。
LR 0xFFFFFFF10xFFFFFFF9 此值称为 EXC_RETURN,用于在 BX LR 时识别返回后应使用的堆栈指针和模式。
PSR 更新 IPSR 位域为当前响应的异常编号 指示处理器正在执行哪个中断,可通过 __get_IPSR() 读取。
SP 入栈完成后指向已更新的栈顶 若线程模式下使用 PSP,已强制切换为 MSP。
CONTROL CONTROL[1] 强制清 0 强制选择 MSP 作为当前 SP。
PRIMASK/FAULTMASK/BASEPRI 根据优先级自动更新 确保当前中断不会被同级或更低优先级中断抢占。
3.5.4 EXC_RETURN 返回值
EXC_RETURN 值 返回模式 使用的堆栈
0xFFFFFFF1 处理者模式 MSP
0xFFFFFFF9 线程模式 MSP
0xFFFFFFFD 线程模式 PSP
3.5.5 中断响应流程时序图

Return

Software

Hardware

中断挂起

入栈 8 个寄存器

取向量: 读取 ISR 地址

更新 PC/LR/PSR/SP

跳转到 ISR

执行 ISR 代码

执行 BX LR

硬件识别 EXC_RETURN

出栈恢复寄存器

返回被中断线程

3.5.6 中断延迟
指标 典型值 说明
中断响应时间 12 个时钟周期 从确认中断到执行 ISR 第一条指令
咬尾中断延迟 6 个时钟周期 连续中断处理时的优化延迟

3.6 异常返回

当 ISR 执行完毕,执行 BX LR 指令时,由于 LR 中存放的是 EXC_RETURN 值,处理器识别出这是一个异常返回请求,硬件会自动执行出栈操作,恢复入栈时的 8 个寄存器值,并恢复 PC 到被中断的代码位置。


4. 结合示例的中断行为说明

为了帮助更好地理解中断响应流程,下面以 RTOS 任务切换中的 PendSV 中断 为例,解释该过程在真实系统中的具体体现。

4.1 场景描述

FreeRTOS 在 SysTick 中断中触发了 PendSV,用于执行任务上下文切换。

4.2 详细硬件行为分解

步骤 操作 寄存器变化 地址变化
1 确认 PendSV 被挂起且没有更高优先级中断 - -
2 入栈:若当前线程使用 PSP,硬件将 PC、xPSR、R0-R3、R12、LR 自动压入当前线程的 PSP 栈 SP 切换到 MSP;PSP 固定指向线程堆栈栈顶 MSP = MSP - 32
3 取向量:读取向量表中 PendSV 的表项 PC 载入 PendSV 入口地址;LR 载入 0xFFFFFFF9 -
4 寄存器更新:IPSR 更新为 PendSV 编号 (14) IPSR = 14 -
5 跳转执行:处理器执行 PendSV 中断服务例程调度代码 - -
6 调度完成:ISR 末尾执行 BX LR,硬件识别 EXC_RETURN 后自动出栈 PC 恢复为新任务的入口地址;SP 切换回 PSP PSP 指向新任务堆栈

4.3 上下文切换代码示例

// PendSV 中断服务例程(简化版)
__attribute__((naked))
void PendSV_Handler(void)
{
    __asm volatile (
        // 保存当前任务现场
        "MRS    R0, PSP                  \n"
        "STMDB  R0!, {R4-R11}            \n"
        "LDR    R1, =pxCurrentTCB        \n"
        "LDR    R2, [R1]                 \n"
        "STR    R0, [R2]                 \n"
        
        // 切换到下一个任务
        "BL     vTaskSwitchContext       \n"
        
        // 恢复新任务现场
        "LDR    R1, =pxCurrentTCB        \n"
        "LDR    R2, [R1]                 \n"
        "LDR    R0, [R2]                 \n"
        "LDMIA  R0!, {R4-R11}            \n"
        "MSR    PSP, R0                  \n"
        
        // 异常返回
        "BX     LR                       \n"
    );
}

4.4 用例总结

通过上述硬件自动入栈、取向量与寄存器更新的机制,Cortex-M3 实现了低延迟、可预测的中断响应。RTOS 任务切换结合双堆栈机制(MSP 用于内核、PSP 用于任务),实现了内核与用户任务的空间隔离,增强了系统的健壮性。


5. 异常类型汇总

异常编号 异常类型 优先级(默认) 说明
1 复位 -3(最高) 系统复位
2 NMI -2 不可屏蔽中断
3 硬故障 -1 各类严重错误
4-10 其他故障 可配置 MemManage、BusFault、UsageFault 等
11 SVC 可配置 系统服务调用
12 调试监视器 可配置 调试相关
13 PendSV 可配置 可悬起的中断,用于任务切换
14 SysTick 可配置 系统滴答定时器
15+ 外部中断 可配置 外设中断(数量由芯片厂商定义)

6. 总结

Cortex-M3 内核通过精心设计的状态模型(线程模式处理者模式)和特权级别(特权级用户级),实现了任务隔离系统保护。其智能化的中断处理机制(NVIC咬尾中断晚到中断)结合硬件自动完成的入栈、取向量和寄存器更新,实现了低延迟、可预测的中断响应,为构建高实时性、高可靠性的嵌入式系统提供了坚实的基础。

核心要点回顾

特性 描述
操作模式 线程模式 + 处理者模式
特权级别 特权级 + 用户级
堆栈指针 MSP + PSP(双堆栈隔离)
中断响应 12 时钟周期 + 硬件自动入栈
优化机制 咬尾中断 + 晚到中断
EXC_RETURN 控制异常返回后的模式与堆栈
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐