Cortex-M3权威指南Cn第八章——笔记

个人学习的笔记,希望帮助能到和我一样阅读Cortex-M3权威指南Cn遇到困难的人。
强烈建议先阅读Cortex-M3权威指南Cn第八章在来观看笔记



在cortex m3 中,中断(异常)常用寄存器

在Cortex-M3中,异常和中断的管理涉及多个寄存器,主要属于嵌套向量中断控制器(NVIC)和系统控制块(SCB)。以下是一些重要的寄存器及其具体作用的详细描述:

一、 NVIC寄存器组(地址范围:0xE000E100 - 0xE000E4FF)

  1. 中断使能寄存器(Interrupt Enable Registers)
    • NVIC_ISER0 - NVIC_ISER7(Interrupt Set-Enable Registers):每个位对应一个中断,写1到某位可使能相应的中断。这些寄存器用于使能中断。
    • NVIC_ICER0 - NVIC_ICER7(Interrupt Clear-Enable Registers):每个位对应一个中断,写1到某位可禁用相应的中断。这些寄存器用于禁用中断。
  2. 中断悬挂寄存器(Interrupt Pending Registers)
    • NVIC_ISPR0 - NVIC_ISPR7(Interrupt Set-Pending Registers):每个位对应一个中断,写1到某位可以将相应中断的状态设置为悬挂(等待处理)。
    • NVIC_ICPR0 - NVIC_ICPR7(Interrupt Clear-Pending Registers):每个位对应一个中断,写1到某位可以清除相应中断的悬挂状态。
  3. 中断活动状态寄存器(Interrupt Active Status Registers)
    • NVIC_IABR0 - NVIC_IABR7(Interrupt Active Bit Registers):每个位对应一个中断,为1表示相应的中断正在被处理(活动状态)。这些寄存器是只读的。
  4. 中断优先级寄存器(Interrupt Priority Registers)
    • NVIC_IPR0 - NVIC_IPR31(Interrupt Priority Registers):每个中断对应一个8位的优先级字段(但通常只使用高4位)。这些寄存器用于设置每个中断的优先级,优先级数值越小,优先级越高。
  5. 软件触发中断寄存器(Software Trigger Interrupt Register)
    • NVIC_STIR(Software Trigger Interrupt Register):通过向此寄存器写入中断编号,可以软件触发相应的中断。

二、 SCB寄存器组(地址范围:0xE000ED00 - 0xE000ED3F)

  1. 中断控制与状态寄存器(Interrupt Control and State Register)
    • SCB_ICSR (Interrupt Control and State Register):提供异常处理的控制和状态信息。主要位段包括:
      • VECTACTIVE:当前正在处理的中断或异常的编号。
      • VECTPENDING:当前悬挂的最高优先级中断或异常的编号。
      • ISRPENDING:表示是否有外部中断处于悬挂状态。
      • PENDSTSET, PENDSTCLR:分别用于悬挂和清除SysTick异常。
      • PENDSVSET, PENDSVCLR:分别用于悬挂和清除PendSV异常。
      • NMIPENDSET:NMI(不可屏蔽中断)的悬挂位。
  2. 向量表偏移寄存器(Vector Table Offset Register)
    • SCB_VTOR(Vector Table Offset Register):指定异常向量表的起始地址。复位后为0,向量表位于0地址。可以将其重定位到其他地址(如RAM或Flash的特定区域)。
  3. 应用中断与复位控制寄存器(Application Interrupt and Reset Control Register)
    • SCB_AIRCR (Application Interrupt and Reset Control Register):用于控制中断优先级分组和系统复位。主要位段包括:
      • PRIGROUP:用于设置中断优先级分组(即将一个8位的优先级寄存器划分为抢占优先级和子优先级两部分)。
      • SYSRESETREQ:写1可请求系统复位。
      • VECTCLRACTIVE:在调试时用于清除活动的中断状态。
      • ENDIANNESS:指示处理器的字节序(只读)。
  4. 系统异常优先级寄存器(System Handler Priority Registers)
    • SCB_SHPR1 - SCB_SHPR3(System Handler Priority Registers):用于设置系统异常的优先级。系统异常(如SVCall、PendSV、SysTick等)的优先级可以通过这些寄存器设置。
  5. 系统异常控制与状态寄存器(System Handler Control and State Register)
    • SCB_SHCSR(System Handler Control and State Register):用于使能系统异常(如用法错误、总线错误、内存管理错误等)以及查询其状态。例如,可以查询当前是否有悬挂的系统异常。

三、 SysTick寄存器(系统定时器,属于系统异常)

  1. SysTick控制和状态寄存器(SysTick Control and Status Register)
    • SysTick_CTRL :控制SysTick定时器的行为和状态。主要位包括:
      • ENABLE:使能SysTick定时器。
      • TICKINT:使能SysTick中断(当计数器减到0时产生异常)。
      • CLKSOURCE:选择时钟源(系统时钟或外部参考时钟)。
      • COUNTFLAG:当计数器减到0时置1,读取该寄存器后清零。
  2. SysTick重载值寄存器(SysTick Reload Value Register)
    • SysTick_LOAD:设置SysTick定时器重载值。当计数器减到0后,下次计数将从该值开始。
  3. SysTick当前值寄存器(SysTick Current Value Register)
    • SysTick_VAL:读取当前计数器的值。写操作会清零该寄存器,同时清除COUNTFLAG标志。

四、 特殊寄存器(通过MRS/MSR指令访问)

  1. 程序状态寄存器(Program Status Register)
    • xPSR:组合了应用程序状态寄存器(APSR)、中断状态寄存器(IPSR)和执行状态寄存器(EPSR)。其中IPSR包含了当前正在处理的中断或异常的编号。
  2. 优先级屏蔽寄存器(Priority Mask Registers)
    • PRIMASK:写1可禁止所有可屏蔽中断(即设置为最高优先级,阻止中断)。
    • FAULTMASK:写1可禁止所有中断和异常(除了NMI)。
    • BASEPRI:设置一个优先级阈值,只有优先级高于此阈值的中断才能被响应。
  3. 控制寄存器(Control Register)
    • CONTROL:控制处理器的操作模式和堆栈选择。例如,可以切换为使用进程堆栈(PSP)而不是主堆栈(MSP)。


在cortex m3 中,NVIC寄存器组

1. 中断使能寄存器(Interrupt Enable Registers)
地址范围0xE000E100 - 0xE000E11C

  • NVIC_ISER00xE000E100 - 控制中断0-31
  • NVIC_ISER10xE000E104 - 控制中断32-63
  • NVIC_ISER20xE000E108 - 控制中断64-95
  • ... 以此类推,直到 NVIC_ISER70xE000E11C - 控制中断224-239
    NVIC_ICER0-7 地址:0xE000E180 - 0xE000E19C
  • 与ISER地址偏移0x80,保持相同的分组结构
    读写规则
  • 写操作:向某位写1执行相应功能(使能或禁用),写0无效
  • 读操作:返回当前使能状态,1=已使能,0=已禁用
  • 特性 :ISER和ICER是配对寄存器,确保操作原子性。当需要修改中断使能状态时,不会被其他中断打断
    中断号映射示例
txt 复制代码
中断号 = 37 的映射计算:
  寄存器索引 = 37 / 32 = 1(使用ISER1/ICER1)
  位位置 = 37 % 32 = 5(第5位)
访问地址:0xE000E104(ISER1)的第5位

详细功能

  • ISER:使能中断,使中断可被处理器响应
  • ICER:禁用中断,即使中断发生也不会被处理
  • 关键点:禁用中断不会清除悬挂状态,中断信号仍可能被悬挂

2. 中断悬挂寄存器(Interrupt Pending Registers)
地址范围0xE000E200 - 0xE000E21C(ISPR)
NVIC_ICPR0-7 地址:0xE000E280 - 0xE000E29C
读写规则

  • 写操作:向某位写1设置或清除悬挂状态,写0无效
  • 读操作:返回当前悬挂状态,1=中断正在悬挂等待处理
  • 重要特性
    • 中断源产生中断信号时,硬件自动设置对应悬挂位
    • 即使中断被禁用(ICER),悬挂位仍可被设置
    • 软件可手动设置悬挂位来模拟中断
      详细功能
  • ISPR:手动悬挂中断,强制中断进入等待处理队列
  • ICPR :清除悬挂状态,通常用于:
    • 中断服务完成后清除状态
    • 丢弃不需要处理的悬挂中断
    • 软件调试时重置中断状态

3. 中断活动状态寄存器(Interrupt Active Status Registers)
地址范围0xE000E300 - 0xE000E31C
读写规则

  • 只读寄存器:软件只能读取,不能写入
  • 读操作:返回1表示中断正在执行(从进入ISR到中断返回期间)
  • 自动管理 :硬件自动设置和清除活动位
    详细功能
  • 实时反映中断执行状态
  • 用于诊断和调试,了解系统中断活动情况
  • 结合悬挂寄存器,可判断中断处理的延迟和积压

4. 中断优先级寄存器(Interrupt Priority Registers)
地址范围0xE000E400 - 0xE000E4EC
组织方式

  • 共32个寄存器(IPR0-IPR31)
  • 每个寄存器32位,分为4个8位字段
  • 每个8位字段对应一个中断的优先级
    中断号到IPR的映射
txt 复制代码
中断号 = N
寄存器索引 = N / 4          // 使用哪个IPR寄存器
字段位置 = (N % 4) * 8      // 在该寄存器中的起始位

示例:中断号15
  寄存器索引 = 15 / 4 = 3   // 使用IPR3
  字段位置 = (15 % 4) * 8 = 3 * 8 = 24
  → IPR3[31:24]用于中断15的优先级

优先级位使用

  • 8位字段中,通常只有高4位[7:4]有效
  • 低4位[3:0]通常读为0,写入被忽略
  • 数值范围:0x00(最高优先级)到0xF0(最低优先级),步长为0x10
  • 优先级分组(PRIGROUP)决定这些位如何划分为抢占优先级和子优先级
    读写规则
  • 可读写,但建议在中断禁用时修改
  • 写入时必须对齐到正确的字节位置

5. 软件触发中断寄存器(Software Trigger Interrupt Register)
地址0xE000EF00
格式

txt 复制代码
位[8:0]:中断编号(0-239)
位[31:9]:保留,必须写0

读写规则

  • 写操作:写入中断编号触发对应中断
  • 读操作:返回不确定值,通常不使用
  • 触发条件 :中断必须已使能(ISER中对应位为1)
    详细功能
  • 软件模拟硬件中断
  • 用于测试中断服务程序
  • 任务间通信和同步
  • 调试时手动触发中断流程

典型中断处理过程:

  1. 中断发生
    • 硬件自动设置NVIC_ISPR对应位(中断悬挂)
  2. 中断响应前
    • NVIC比较所有悬挂中断的优先级
    • 选择最高优先级中断准备响应
  3. 中断响应
    • 硬件清除NVIC_ISPR对应位(清除悬挂)
    • 硬件设置NVIC_IABR对应位(标记为活动)
    • 处理器跳转到中断服务程序
  4. 中断处理中
    • NVIC_IABR保持为1
    • 可被更高优先级中断抢占
  5. 中断返回
    • 硬件清除NVIC_IABR对应位
    • 如果有其他悬挂中断,继续处理

这里使用比喻来方便我们理解:

比喻:医院急诊室系统:

将NVIC寄存器组比作一个现代化医院急诊室管理系统
1. ISER/ICER - 挂号窗口与停诊通知

  • ISER(挂号窗口):病人(中断)在此登记,获得就诊资格。登记后,医院(处理器)才会关注这个病人
  • ICER (停诊通知):取消某类病人的就诊资格,但已经挂号的病人仍在等待
    2. ISPR/ICPR - 候诊名单管理
  • ISPR(新增候诊):新病人到达或医生手动添加病人到候诊名单
  • ICPR (移除名单):病人放弃等待、转院或误登记时从名单移除
    3. IABR - 诊室状态显示屏
  • 只读显示屏:显示正在接受治疗的病人
  • 每个诊室(处理器核心)一次只治疗一个病人
  • 显示屏实时更新,病人开始治疗时亮灯,离开时灭灯
    4. IPR0-IPR31 - 病情分级卡
  • 每个病人有一张分级卡:记录病情严重程度(优先级)
  • 分级规则 (PRIGROUP):医院统一规定如何解读分级卡
    • 例如:前4位表示紧急程度(能否插队),后4位表示同类病人的细微差别
  • 分诊台 (NVIC比较逻辑):持续扫描候诊名单,选择病情最紧急的病人
    5. STIR - 医生紧急呼叫按钮
  • 医生手动触发:当需要立即处理某个特定病例时使用
  • 前提条件:病人必须已在系统登记(中断已使能)
  • 使用场景:紧急会诊、测试医疗流程、内部协调

系统工作流程比喻:
场景:心脏病突发患者(高优先级中断)和感冒患者(低优先级中断)同时到达

  1. 登记:两者都在ISER挂号窗口登记(中断使能)
  2. 候诊:ISPR自动将两人加入候诊名单(中断悬挂)
  3. 分诊
    • 分诊台(NVIC)读取两人的病情分级卡(IPR)
    • 心脏病:优先级0x10(高)
    • 感冒:优先级0xE0(低)
    • 选择心脏病患者优先处理
  4. 治疗
    • IABR显示屏显示"心脏病治疗中"
    • 感冒患者继续在候诊名单(ISPR)等待
  5. 特殊情况
    • 如果心脏病治疗中,来了更紧急的枪伤患者(更高优先级):
      • 心脏病治疗暂停(被抢占)
      • 枪伤患者进入诊室,IABR更新显示
    • 如果感冒患者等不及离开:通过ICPR从候诊名单移除
  6. 医生主动呼叫
    • 住院部需要急诊会诊:医生按下STIR按钮,指定"内科医生3号"
    • 对应医生(中断服务程序)立即前往急诊室

特点

  • 原子操作:挂号窗口的设计确保不会同时登记和取消同一病人
  • 状态独立:候诊状态、治疗状态、登记状态相互独立管理
  • 优先级动态:病人病情变化(优先级修改)实时影响分诊决策
  • 软件触发:医院内部协调不依赖外部病人到达


在cortex m3 中,SCB寄存器组

1. 中断控制与状态寄存器(SCB_ICSR)
地址0xE000ED04
位段详细功能

  • VECTACTIVE[8:0] (位8:0):当前活动异常的编号
    • 只读字段
    • 0 = 线程模式(无活动异常)
    • 1-15 = 系统异常编号
    • 16-255 = 外部中断编号(IRQn = VECTACTIVE - 16)
    • 用途:诊断当前正在执行哪个异常处理程序
  • RETTOBASE (位11):中断返回指示位
    • 只读字段
    • 1 = 中断返回后将返回到基础级别(线程模式或没有嵌套)
    • 0 = 中断返回后将返回到另一个中断(有中断嵌套)
    • 用途:判断当前中断嵌套状态
  • VECTPENDING[8:0] (位20:12):最高优先级悬挂异常的编号
    • 只读字段
    • 0 = 没有悬挂的异常
    • 非0 = 等待处理的最高优先级异常编号
    • 用途:查看下一个将被处理的异常
  • ISRPENDING (位22):外部中断悬挂标志
    • 只读字段
    • 1 = 至少有一个外部中断(IRQ)正在悬挂
    • 0 = 没有外部中断悬挂
    • 与VECTPENDING的区别:VECTPENDING包含所有异常,ISRPENDING只针对外部中断
  • PENDSTSET (位26):SysTick异常悬挂设置位
    • 读写位
    • 写1 = 将SysTick异常设置为悬挂状态
    • 读 = 返回当前SysTick悬挂状态(1=悬挂,0=未悬挂)
  • PENDSTCLR (位25):SysTick异常悬挂清除位
    • 读写位
    • 写1 = 清除SysTick异常悬挂状态
    • 读 = 通常返回0,但反映操作状态
  • PENDSVSET (位28):PendSV异常悬挂设置位
    • 读写位
    • 写1 = 将PendSV异常设置为悬挂状态
    • 读 = 返回当前PendSV悬挂状态
  • PENDSVCLR (位27):PendSV异常悬挂清除位
    • 读写位
    • 写1 = 清除PendSV异常悬挂状态
    • 读 = 通常返回0
  • NMIPENDSET (位31):NMI悬挂设置位
    • 读写位
    • 写1 = 将NMI设置为悬挂状态(如果允许)
    • 读 = 返回当前NMI悬挂状态
    • 注意 :NMI不可屏蔽,一旦悬挂会立即响应
      读写规则
  • 状态位(VECTACTIVE、RETTOBASE、VECTPENDING、ISRPENDING)只读
  • 悬挂控制位(PENDSTSET/CLR、PENDSVSET/CLR)读写,但写入1执行操作,写入0无效
  • 多个悬挂位可能同时有效,NVIC根据优先级选择响应顺序

2. 向量表偏移寄存器(SCB_VTOR)
地址0xE000ED08
格式

txt 复制代码
位[31:30]:保留,必须为0
位[29:7]:向量表基地址的[29:7]位(TBLOFF)
位[6:0]:保留,必须为0

功能详解

  • 复位值:0x00000000(向量表位于地址0)
  • 对齐要求:向量表基地址必须至少对齐到128字节(0x80)边界
  • 向量表内容
    • 偏移0x00:主堆栈指针(MSP)初始值
    • 偏移0x04:复位向量(程序入口)
    • 偏移0x08:NMI处理程序地址
    • 偏移0x0C:硬错误处理程序地址
    • ... 依此类推,每个异常占用4字节
      重定位场景
  1. 从RAM运行程序:向量表复制到RAM,VTOR指向RAM地址
  2. 引导加载程序:引导程序在Flash,应用程序在另一Flash区域
  3. 多任务系统 :不同任务有自己的异常处理程序
    读写规则
  • 可读写,但通常只在系统初始化时设置
  • 修改前建议禁用全局中断
  • 地址必须满足对齐要求

3. 应用中断与复位控制寄存器(SCB_AIRCR)
地址0xE000ED0C
特殊写入规则

  • VECTKEY字段 (位31:16):必须写入0x05FA才能修改此寄存器
  • VECTKEYSTAT字段 (位31:16):读取时返回0xFA05
    位段详细功能
  • PRIGROUP[10:8](位10:8):优先级分组设置
txt 复制代码
分组值 | 抢占优先级位宽 | 子优先级位宽 | 抢占级数 | 子优先级级数
-------|----------------|-------------|----------|-------------
0      | 7 bits         | 1 bit       | 128      | 2
1      | 6 bits         | 2 bits      | 64       | 4
2      | 5 bits         | 3 bits      | 32       | 8
3      | 4 bits         | 4 bits      | 16       | 16
4      | 3 bits         | 5 bits      | 8        | 32
5      | 2 bits         | 6 bits      | 4        | 64
6      | 1 bit          | 7 bits      | 2        | 128
7      | 0 bits         | 8 bits      | 1        | 256
  • 功能 :决定如何解析8位优先级字段
    • 示例:PRIGROUP=4,则优先级字段高3位为抢占优先级,低5位为子优先级
  • SYSRESETREQ (位2):系统复位请求
    • 写1 = 请求整个系统复位(除调试模块外)
    • 读 = 通常返回0
    • 用途:软件触发系统重启
  • VECTCLRACTIVE (位1):清除所有异常活动状态
    • 写1 = 在调试时清除所有异常的活动状态
    • 读 = 通常返回0
    • 用途:调试器让处理器从异常状态恢复
  • ENDIANNESS (位15):字节序指示位
    • 只读位
    • 0 = 小端模式(Cortex-M3固定为小端)
    • 1 = 大端模式(Cortex-M3不支持)
      读写规则
  • 写操作必须包含正确的VECTKEY
  • 读操作直接读取当前值
  • 修改PRIGROUP可能影响正在处理的中断,建议在中断禁用时修改

4. 系统异常优先级寄存器(SCB_SHPR1-SCB_SHPR3)
地址

  • SCB_SHPR10xE000ED18
  • SCB_SHPR20x0000ED1C
  • SCB_SHPR30xE000ED20
    详细映射
txt 复制代码
SHPR1(0xE000ED18):
  位[31:24]:保留
  位[23:16]:UsageFault(异常6)优先级
  位[15:8]:BusFault(异常5)优先级
  位[7:0]:MemManage(异常4)优先级

SHPR2(0xE000ED1C):
  位[31:24]:SVCall(异常11)优先级
  位[23:16]:保留
  位[15:8]:保留
  位[7:0]:保留

SHPR3(0xE000ED20):
  位[31:24]:PendSV(异常14)优先级
  位[23:16]:SysTick(异常15)优先级
  位[15:8]:保留
  位[7:0]:保留

功能详解

  • 每个8位字段结构与NVIC_IPR相同(通常只使用高4位)
  • 系统异常编号范围:1-15
  • 重要系统异常
    • 2: NMI(不可屏蔽中断,优先级固定,不可配置)
    • 3: HardFault(硬错误,优先级固定)
    • 4: MemManage(内存管理错误)
    • 5: BusFault(总线错误)
    • 6: UsageFault(用法错误)
    • 11: SVCall(系统服务调用)
    • 14: PendSV(可悬挂系统调用)
    • 15: SysTick(系统定时器)
      读写规则
  • 可读写,但某些系统异常优先级有固定范围
  • 建议在系统初始化时配置

5. 系统异常控制与状态寄存器(SCB_SHCSR)
地址0xE000ED24
位段详细功能
使能控制位

  • USGFAULTENA (位18):使能UsageFault异常
    • 1 = 使能,0 = 禁用
    • 禁用时,UsageFault变为硬错误
  • BUSFAULTENA (位17):使能BusFault异常
    • 1 = 使能,0 = 禁用
    • 禁用时,BusFault变为硬错误
  • MEMFAULTENA (位16):使能MemManage异常
    • 1 = 使能,0 = 禁用
    • 禁用时,MemManage变为硬错误
      悬挂状态位
  • SVCALLPENDED(位15):SVCall悬挂状态
  • BUSFAULTPENDED(位14):BusFault悬挂状态
  • MEMFAULTPENDED(位13):MemManage悬挂状态
  • USGFAULTPENDED (位12):UsageFault悬挂状态
    活动状态位
  • SYSTICKACT(位11):SysTick活动状态
  • PENDSVACT(位10):PendSV活动状态
  • USGFAULTACT(位3):UsageFault活动状态
  • BUSFAULTACT(位1):BusFault活动状态
  • MEMFAULTACT(位0):MemManage活动状态
  • SVCallACT (位7):SVCall活动状态
    读写规则
  • 使能控制位可读写,但修改可能影响异常行为
  • 悬挂状态位:通常只读,但某些位写入1可清除悬挂状态
  • 活动状态位:只读,由硬件自动管理

异常处理流程示例:

  1. 异常发生 :MemManage错误(系统异常4)
    • 如果MEMFAULTENA=1,则进入MemManage异常
    • 如果MEMFAULTENA=0,则升级为HardFault(异常3)
  2. 状态更新
    • SCB_ICSR.VECTACTIVE = 4
    • SCB_SHCSR.MEMFAULTACT = 1
  3. 优先级比较
    • 使用SCB_SHPR1配置的MemManage优先级
    • 与PRIGROUP设置的分组规则结合
  4. 异常返回
    • SCB_SHCSR.MEMFAULTACT = 0
    • 根据SCB_ICSR.RETTOBASE决定返回路径

这里使用几个比喻来方便我们理解:
比喻一:系统工作流程

想象一个大型工厂的操作系统调度中心:

  1. 正常运行时
    • 调度中心大屏(ICSR)显示VECTACTIVE为0,表示没有异常,工厂正常生产。
    • 向量表仓库(VTOR)指向默认位置,存储着各种异常处理程序地址。
  2. 发生外部中断
    • 流水线发出故障信号(外部中断),ISRPENDING灯亮起。
    • 大屏显示VECTPENDING为该故障的工号。
    • 调度中心根据优先级比较,如果当前没有更高优先级的任务,则开始处理此故障。
  3. 系统调用
    • 工人发出系统调用请求(SVCall),调度中心设置SVCall的悬挂状态。
    • 由于SVCall优先级较高(通过SHPR2设置),调度中心暂停当前工作,处理系统调用。
  4. 任务切换
    • 系统定时器(SysTick)发出时间片用完的信号,调度中心通过PENDSTSET悬挂SysTick异常。
    • 调度中心决定进行任务切换,于是通过PENDSVSET悬挂PendSV异常。
    • 由于PendSV的优先级被设为最低(通过SHPR3),它会等到其他紧急任务都处理完后才执行,从而安全地进行任务切换。
  5. 系统错误处理
    • 如果发生内存访问错误(MemManage Fault),且使能了该异常(SHCSR中MEMFAULTENA为1),则错误处理程序被调用。
    • 错误处理期间,大屏显示MEMFAULTACT为1,表示正在处理内存管理错误。
  6. 系统复位
    • 工厂出现严重故障,无法通过常规手段恢复。调度员按下紧急复位按钮(AIRCR中的SYSRESETREQ),整个工厂重启。

比喻二:航空交通管制中心

将SCB寄存器组比作一个现代化航空交通管制中心(ATC),负责管理整个空域的系统级飞行规则和状态监控。

1. SCB_ICSR - 空中交通状态显示屏

这是管制员面前的主显示屏,显示实时空中状态:

  • VECTACTIVE :当前正在通话的飞机呼号
    • 显示哪架飞机正在执行操作或报告问题
    • "0"表示空域清空,没有飞机在操作
  • VECTPENDING :等待队列中最优先的飞机呼号
    • 显示下一架将被允许操作的飞机
  • RETTOBASE :返航指示器
    • 绿灯:飞机完成操作后将返回基地(无嵌套)
    • 红灯:飞机操作后还要接替另一架飞机(有嵌套)
  • ISRPENDING :外部飞机等待指示灯
    • 红灯闪烁:有空域外的飞机请求进入
  • PENDSTSET/CLR :定期调度计时器控制
    • 管制员可手动设置/清除定期航班调度信号
  • PENDSVSET/CLR :航班交接控制
    • 用于控制航班之间的交接过程
  • NMIPENDSET :紧急情况红色按钮
    • 按下后立即触发最高优先级响应

2. SCB_VTOR - 飞行规程手册存放位置

这是存放所有飞行操作手册(异常处理程序)的仓库位置指示器:

  • 默认位置:主控室的标准书架(地址0)
  • 可重定位 :管制中心可决定将手册移到:
    • 快速存取室(RAM):加快查阅速度
    • 备用控制中心(Flash其他区域):冗余备份
    • 不同机场的分控中心:分布式管理

3. SCB_AIRCR - 空域规则制定与紧急控制台

这是制定飞行规则和应急控制的主控制台:

  • PRIGROUP:空域优先级划分规则
txt 复制代码
例如选择规则4:
  - 4位用于决定飞机能否互相打断(抢占)
  - 0位用于同级别内的细微排序
  - 结果:16个抢占级别,无子级别
  • 管制员统一规定:军用机(高抢占级)可随时打断民用机
  • SYSRESETREQ :全空域紧急清空按钮
    • 在发生不可控危险时,管制员按下此按钮
    • 所有飞机立即返航,空域完全清空
  • VECTCLRACTIVE :异常状态清除按钮
    • 调试员在模拟训练时使用
    • 清除所有飞机的"正在操作"状态
  • ENDIANNESS :通讯协议格式标签
    • 显示"小端模式"(Cortex-M3固定格式)

4. SCB_SHPR1-SCB_SHPR3 - 特殊飞机优先级登记表

这是记录特殊类型飞机优先级的登记表:

  • SHPR1表 :紧急救援飞机的优先级
    • 医疗救援机(MemManage)
    • 燃油泄漏处理机(BusFault)
    • 违规飞行纠正机(UsageFault)
  • SHPR2表 :塔台指令响应优先级
    • 塔台直接指令接收机(SVCall)
  • SHPR3表 :系统调度飞机优先级
    • 定期航班交接机(PendSV)
    • 定时巡逻机(SysTick)
      登记规则:管制员为每类飞机分配一个紧急程度编号(优先级)

5. SCB_SHCSR - 特殊飞机状态监控板

这是监控特殊类型飞机状态的专用面板:
左侧区域(使能开关)

  • 三个大开关:
    • 医疗救援系统开关(MEMFAULTENA)
    • 燃油泄漏响应开关(BUSFAULTENA)
    • 违规飞行监控开关(USGFAULTENA)
  • 开关打开:相应系统激活
  • 开关关闭:问题升级为最高紧急级别
    中间区域(等待状态灯)
  • 四盏黄灯,分别显示:
    • 塔台指令等待(SVCALLPENDED)
    • 燃油泄漏报告等待(BUSFAULTPENDED)
    • 医疗救援请求等待(MEMFAULTPENDED)
    • 违规飞行警报等待(USGFAULTPENDED)
      右侧区域(活动状态灯)
  • 多盏绿灯,显示哪些飞机正在执行任务:
    • 定时巡逻机工作中(SYSTICKACT)
    • 航班交接进行中(PENDSVACT)
    • 塔台指令执行中(SVCallACT)
    • 各紧急类型飞机工作中

空域管理场景
场景:繁忙国际机场的空域管理

  1. 正常运作
    • 主显示屏(ICSR)显示VECTACTIVE=0,空域正常
    • 飞行手册(VTOR)在主控室标准位置
    • 空域规则(AIRCR)设定为"军用优先"模式(PRIGROUP=4)
  2. 紧急情况发生
    • 医疗救援机报告紧急情况(MemManage错误)
    • 如果医疗系统开关(MEMFAULTENA)打开:
      • 医疗救援机按SHPR1登记优先级响应
      • 状态板亮起"医疗救援工作中"绿灯(MEMFAULTACT=1)
    • 如果开关关闭:直接触发最高紧急响应
  3. 多任务处理
    • 塔台发出调度指令(SVCall)
    • 定期巡逻机时间到(SysTick)
    • 航班需要交接(PendSV)
    • 管制中心根据SHPR2/SHPR3的优先级安排:
      1. 塔台指令最先响应(高优先级)
      2. 医疗救援同时进行
      3. 定期巡逻机随后
      4. 航班交接最后(PendSV设为最低优先级)
  4. 空域重配置
    • 夜间模式:将飞行手册移到快速存取室(VTOR指向RAM)
    • 调整规则:改为"民航优先"模式(修改PRIGROUP)
    • 关闭部分监控系统(修改SHCSR使能位)
  5. 灾难恢复
    • 空域完全失控:管制员按下紧急清空按钮(SYSRESETREQ)
    • 所有飞机强制返航,系统重启

比喻三:学校教务处管理系统
SCB寄存器组就像学校的教务处,负责管理所有的课程安排(异常处理)和教学规则。

1. SCB_ICSR - 当前课堂状态显示屏

这个显示屏显示当前学校里的上课情况。

  • VECTACTIVE :正在上课的班级和课程编号。
    • 比如"3年级2班数学课",对应一个课程编号。
    • 如果显示0,表示现在没有班级在上课(比如课间)。
  • VECTPENDING :下一个要上课的班级和课程。
    • 显示已经打上课铃但老师还没进教室的班级中,优先级最高的课程。
  • RETTOBASE :放学回家指示灯。
    • 绿灯:这节课上完后,学生直接回家(没有嵌套,返回基础线程)。
    • 红灯:这节课上完后,学生还要去上另一节课(有嵌套,返回另一个中断)。
  • ISRPENDING :校外活动申请指示灯。
    • 红灯闪烁:有校外活动(外部中断)申请,等待教务处批准。
  • PENDSTSET/CLR :上下课铃声控制。
    • 教务处可以手动触发下课铃声(清除)或上课铃声(设置)。
  • PENDSVSET/CLR :调课控制。
    • 教务处可以手动设置或清除调课通知,用于协调课程安排。
  • NMIPENDSET :紧急事件按钮。
    • 比如火警,按下后所有课程立即停止,优先处理紧急事件。

2. SCB_VTOR - 课程表存放位置

教务处有一本总课程表(异常向量表),记录了每门课的教室和老师(异常处理函数的地址)。

  • 默认位置:教务处的文件柜(地址0)。
  • 可重定位 :教务处可以把课程表复制到:
    • 教师办公室(RAM):方便老师快速查看。
    • 学校服务器(Flash其他区域):备份。
    • 年级组办公室(不同地址):分权管理。

3. SCB_AIRCR - 学校教学规则制定与紧急广播

教务处制定全校的教学规则,并拥有紧急广播系统。

  • PRIGROUP :课程优先级划分规则。
    • 比如,将课程分为主科(语文、数学、英语)和副科(体育、音乐、美术)。
    • 规则决定主科是否可以打断副科(抢占),以及同为主科时数学和语文哪个先上(子优先级)。
  • SYSRESETREQ :全校紧急放学按钮。
    • 遇到极端天气或紧急情况,教务处按下按钮,全校停课,所有学生回家。
  • VECTCLRACTIVE :课堂状态清除按钮(用于模拟演练)。
    • 在消防演练时,教务处可以清除所有上课状态,让演练顺利进行。
  • ENDIANNESS :学校文件格式标签。
    • 显示"小端格式"(Cortex-M3固定)。

4. SCB_SHPR1-SCB_SHPR3 - 特殊课程优先级登记表

教务处为一些特殊课程设定优先级。

  • SHPR1表 :处理学生突发事件的课程优先级。
    • 学生生病处理(MemManage)
    • 校车故障处理(BusFault)
    • 学生违规处理(UsageFault)
  • SHPR2表 :教务处直接通知的课程优先级。
    • 教务处广播通知(SVCall)
  • SHPR3表 :学校日常安排课程优先级。
    • 调课处理(PendSV)
    • 课间操(SysTick)

5. SCB_SHCSR - 特殊课程状态监控板

教务处墙上有一块监控板,显示特殊课程的状态。

  • 左侧区域(使能开关)
    • 学生生病处理系统开关(MEMFAULTENA)
    • 校车故障响应开关(BUSFAULTENA)
    • 学生违规监控开关(USGFAULTENA)
  • 中间区域(等待状态灯)
    • 教务处通知等待(SVCALLPENDED)
    • 校车故障报告等待(BUSFAULTPENDED)
    • 学生生病报告等待(MEMFAULTPENDED)
    • 学生违规报告等待(USGFAULTPENDED)
  • 右侧区域(活动状态灯)
    • 课间操进行中(SYSTICKACT)
    • 调课处理中(PENDSVACT)
    • 教务处通知执行中(SVCallACT)
    • 以及各突发事件处理中

学校管理场景

  1. 正常上课
    • 显示屏显示VECTACTIVE=0(课间休息)。
    • 课程表在教务处文件柜(VTOR默认地址)。
    • 教学规则设定为"主科优先"(PRIGROUP=4)。
  2. 突发事件
    • 有学生生病(MemManage错误)。
    • 如果学生生病处理系统开关打开(MEMFAULTENA=1):
      • 按照SHPR1登记的优先级处理(比如先送医务室)。
      • 监控板亮起"学生生病处理中"绿灯(MEMFAULTACT=1)。
    • 如果开关关闭,则直接升级为紧急事件(HardFault)。
  3. 多任务处理
    • 教务处广播通知(SVCall)。
    • 课间操时间到(SysTick)。
    • 需要调课(PendSV)。
    • 教务处根据SHPR2/SHPR3的优先级安排:
      1. 先处理广播通知(高优先级)。
      2. 同时处理学生生病事件。
      3. 然后做课间操。
      4. 最后处理调课(PendSV通常设最低优先级)。
  4. 教学调整
    • 期末考试期间,将课程表复制到教师办公室(VTOR重定位到RAM)以便快速调整。
    • 调整规则为"副科也可打断主科"(修改PRIGROUP)。
    • 关闭学生违规监控系统(修改SHCSR使能位)。
  5. 紧急情况
    • 学校出现严重安全威胁,教务处按下全校紧急放学按钮(SYSRESETREQ)。
    • 所有课程停止,学生撤离,系统重启。


在cortex m3 中,SysTick寄存器

SysTick寄存器详解

SysTick控制和状态寄存器(SysTick_CTRL)
地址0xE000E010
位段详细功能

  • ENABLE(位0) :SysTick定时器使能位
    • 0 = 定时器禁用
    • 1 = 定时器使能
    • 功能:启动或停止SysTick计数器
    • 注意:定时器使能后立即开始从当前值递减计数
  • TICKINT(位1) :SysTick中断使能位
    • 0 = 计数到0时不产生异常
    • 1 = 计数到0时产生SysTick异常(中断)
    • 功能:控制是否在计数到0时触发中断
    • 注意:这是SysTick异常的核心控制位
  • CLKSOURCE(位2) :时钟源选择位
    • 0 = 使用外部参考时钟(通常为AHB时钟/8)
    • 1 = 使用处理器时钟(AHB时钟)
    • 功能:选择计数器的时钟源
    • 实际应用
      • 系统时钟 = 72MHz时:
        • CLKSOURCE=1:每1/72MHz ≈ 13.9ns计数一次
        • CLKSOURCE=0:每(1/72MHz)×8 ≈ 111.1ns计数一次
  • COUNTFLAG(位16) :计数到0标志位
    • 只读位
    • 0 = 计数器未计数到0
    • 1 = 计数器已计数到0(自上次读取该寄存器后)
    • 特殊行为:读取该寄存器时自动清零
    • 用途 :轮询方式检测定时时间到达(不使用中断时)
      读写规则
  • 位0-2可读写
  • 位16只读,读取时自动清零
  • 其他位保留,写0,读为0

SysTick重载值寄存器(SysTick_LOAD)
地址0xE000E014
格式

  • 位[23:0]:重载值(RELOAD)
  • 位[31:24] :保留,必须为0
    功能详解
  • 作用:设置计数器递减的起始值
  • 工作流程
    1. 计数器从LOAD值开始递减
    2. 减到0时,如果ENABLE=1,自动重载LOAD值并继续
    3. 减到0时,如果TICKINT=1,产生SysTick异常
  • 最大计数值:2²⁴ - 1 = 16,777,215
  • 定时周期计算
txt 复制代码
定时时间 = (LOAD + 1) × 时钟周期
例如:系统时钟=72MHz,LOAD=71999
定时时间 = (71999 + 1) × (1/72MHz) = 1ms

读写规则

  • 可读写,24位有效
  • 写入时,如果计数器正在运行,新值在下次重载时生效
  • 不能写入0xFFFFFF以上的值

SysTick当前值寄存器(SysTick_VAL)
地址0x000E018
格式

  • 位[23:0]:当前计数值(CURRENT)
  • 位[31:24] :保留,读为0
    功能详解
  • 读操作:返回当前计数器的值
  • 写操作
    • 写入任何值都会将计数器清零
    • 同时清除COUNTFLAG标志
    • 重要:写入不会触发重载,计数器清零后,下一个时钟周期会从LOAD值重新开始递减(如果使能了定时器)
  • 用途
    1. 读取当前剩余计数值
    2. 软件清零计数器
    3. 同步计数器(在某些应用中)
      读写规则
  • 可读写,24位有效
  • 写入操作具有"副作用"(清零计数器并清除COUNTFLAG)

SysTick异常详解

异常编号 :15(系统异常中最后一个)
异常优先级 :通过SCB_SHPR3寄存器的PRI_15字段(位31:24)设置
为什么要有SysTick异常?

  1. 操作系统时基:为RTOS提供精确的定时心跳
  2. 任务调度:驱动任务时间片轮转
  3. 延时函数:实现精确的软件延时
  4. 性能测量:测量代码执行时间
  5. 系统监控:超时检测、看门狗等
  6. 独立于外设定时器:不依赖芯片特定的定时器外设,提高可移植性

与其他定时器的区别

  1. 内核集成:SysTick是Cortex-M3内核的一部分,所有兼容芯片都有
  2. 简化编程:寄存器少,配置简单
  3. 确定行为:不受芯片厂商实现差异影响

这里我们使用比喻来了解他:
比喻一:心脏与脉搏

将SysTick比作人体的心脏和脉搏系统

SysTick_CTRL - 心脏控制中枢

  • ENABLE开关 :心脏起搏器开关
    • 打开:心脏开始跳动
    • 关闭:心脏停止
  • TICKINT开关 :神经系统连接开关
    • 打开:每次心跳向大脑发送信号
    • 关闭:心跳但不通知大脑
  • CLKSOURCE选择 :心跳节奏选择
    • 快速节奏:正常心跳(系统时钟)
    • 慢速节奏:休息时心跳(外部时钟/8)
  • COUNTFLAG标志 :脉搏检测点
    • 每次心跳到最低点时亮起
    • 医生(软件)检查后自动熄灭

SysTick_LOAD - 心跳间隔设置

  • 设置值 :决定两次心跳之间的时间间隔
    • 比如设置为每分钟60次(LOAD对应值)
    • 设置值越大,心跳越慢
    • 设置值越小,心跳越快

SysTick_VAL - 当前心跳状态

  • 读操作 :听诊器听心跳
    • 听到当前心跳到什么位置了
    • 还有多久到下一次心跳
  • 写操作 :心脏电击复位
    • 任何电击都会让心跳立即归零
    • 然后按照设定间隔重新开始

人体系统工作流程

  1. 系统启动 (身体苏醒):
    • 医生(操作系统)设置心跳间隔(LOAD=71999,1ms一次)
    • 打开心脏起搏器(ENABLE=1)
    • 连接神经系统(TICKINT=1)
    • 选择正常节奏(CLKSOURCE=1,系统时钟)
  2. 正常心跳
    • 心脏从LOAD值开始递减(心跳从高点向低点)
    • 每次到0(心跳完成):
      • 自动重载LOAD值(准备下一次心跳)
      • 向大脑发送信号(SysTick异常)
      • COUNTFLAG亮起(脉搏点)
  3. 大脑响应 (中断服务程序):
    • 大脑收到心跳信号
    • 检查身体各部位状态(调度器检查任务)
    • 决定是否切换活动(任务切换)
    • 更新身体时钟(系统时间累加)
  4. 特殊情况
    • 检查脉搏:医生手动检查COUNTFLAG(轮询方式)
    • 调整心率:修改LOAD值改变心跳间隔
    • 心脏复位:写入VAL重置心跳周期
    • 心脏停跳:关闭ENABLE(休眠模式)

比喻二(RTOS中):工厂流水线的节拍器

在RTOS中,SysTick就像工厂流水线的节拍器 ,控制整个生产节奏:
为什么需要独立的节拍器(SysTick)?

  1. 统一节奏
    • 所有生产线(任务)使用相同的节拍
    • 保证生产(任务执行)的同步性
    • 避免不同产线(外设定时器)节奏不一致
  2. 精确调度
    • 时间片轮转 :每个工人(任务)工作固定节拍数
      • 节拍器响 → 切换工人
      • 保证每个工人都有公平的工作时间
    • 优先级调度
      • 高优先级任务:可以占用多个节拍
      • 低优先级任务:等待空闲节拍
  3. 系统时间基准
    • 记录工厂运行了多久(系统运行时间)
    • 计算产品生产时间(任务执行时间)
    • 安排生产计划(定时任务)
  4. 延时控制
    • 工人休息固定节拍数(任务延时)
    • 等待物料到达的超时检测(同步超时)
      RTOS中的SysTick配置示例
c 复制代码
// RTOS初始化时配置SysTick
void RTOS_SysTick_Init(void) {
    // 设置1ms心跳(假设系统时钟72MHz)
    SysTick_LOAD = 71999;  // 72MHz/1000Hz - 1
    
    // 设置SysTick中断优先级(较低,可被其他中断抢占)
    SCB_SHPR3 = (SCB_SHPR3 & 0x00FFFFFF) | (0xE0 << 24);
    
    // 启动SysTick:使能 + 中断 + 系统时钟
    SysTick_CTRL = (1 << 0) | (1 << 1) | (1 << 2);
}

// SysTick中断服务程序(简化版)
void SysTick_Handler(void) {
    // 1. 系统时钟累加
    SystemTime_ms++;
    
    // 2. 更新任务延时
    for(每个任务) {
        if(任务延时 > 0) 任务延时--;
    }
    
    // 3. 检查任务调度
    if(当前任务时间片用完 || 有更高优先级任务就绪) {
        触发任务调度();
    }
}

工厂节拍器场景
场景:汽车装配工厂有三条生产线(任务):

  1. 发动机装配线 (高优先级任务):
    • 每10个节拍必须完成一台发动机
    • 节拍器每响一次,完成一部分工作
  2. 车身装配线 (中优先级任务):
    • 每20个节拍完成一个车身
    • 在发动机线空闲时获得更多节拍
  3. 喷漆线 (低优先级任务):
    • 每30个节拍完成喷漆
    • 只有前两条线都空闲时才工作

节拍器(SysTick)工作

  • 节拍间隔:1秒(LOAD值决定)
  • 每响一次
    • 生产线主任(调度器)检查各线进度
    • 决定下一节拍哪个线工作
    • 记录总生产时间

优势

  1. 公平性:每个任务按时间片工作
  2. 响应性:高优先级任务及时响应
  3. 可预测性:系统行为时间可预测
  4. 可移植性 :换工厂(芯片)只需调整节拍间隔(LOAD值)
    为什么单独提出SysTick?
  • 标准化:所有Cortex-M3芯片都有相同SysTick
  • 简化性:比配置外设定时器简单
  • 确定性:不受其他外设影响
  • 低开销:中断处理效率高
  • 核心功能:RTOS的"心跳",没有它RTOS无法工作


在cortex m3 中,特殊寄存器

程序状态寄存器(xPSR)

xPSR 实际上是三个独立状态寄存器的组合视图,通过不同的访问名称区分:

1. APSR(应用程序状态寄存器)

位[31:27] - ALU标志位

  • N(位31) :负数标志(Negative)
    • 当算术/逻辑运算结果为负时置1
    • 等于结果的最高位(符号位)
  • Z(位30) :零标志(Zero)
    • 当运算结果为零时置1
  • C(位29) :进位/借位标志(Carry)
    • 加法运算产生进位时置1
    • 减法运算没有借位时置1
    • 移位/循环操作时存放移出的位
  • V(位28) :溢出标志(Overflow)
    • 有符号数运算溢出时置1
  • Q(位27) :饱和标志(Saturation)
    • 当SSAT/USAT饱和指令发生饱和时置1
    • 需要手动清除
      位[19:16] - GE标志
  • GE[3:0] :大于或等于标志
    • 用于SIMD(单指令多数据)指令
    • 并行比较多个字节或半字的结果
2. IPSR(中断程序状态寄存器)

位[8:0] - 异常编号

  • 0:线程模式(没有异常活动)
  • 1-15 :系统异常编号
    • 1:复位
    • 2:NMI(不可屏蔽中断)
    • 3:硬错误
    • 4:内存管理错误
    • 5:总线错误
    • 6:用法错误
    • 7-10:保留
    • 11:SVCall
    • 12:调试监视器
    • 13:保留
    • 14:PendSV
    • 15:SysTick
  • 16及以上:外部中断编号(IRQn = 值 - 16)
3. EPSR(执行程序状态寄存器)

关键位

  • T(位24):Thumb状态位

    • 必须为1(Cortex-M3只运行Thumb指令)
    • 为0会导致用法错误
  • ICI/IT(位[26:25,15:10]):中断继续和If-Then块状态

    • 用于被打断的LDM/STM指令的恢复
    • 用于IT(If-Then)指令块的状态跟踪

访问方式

assembly 复制代码
MRS R0, APSR        ; 只读取APSR部分
MRS R0, IPSR        ; 只读取IPSR部分  
MRS R0, EPSR        ; 只读取EPSR部分
MRS R0, PSR         ; 读取组合的xPSR
MSR APSR, R0        ; 只写入APSR部分(只能写标志位)
MSR PSR, R0         ; 写入组合的xPSR(有限制)

优先级屏蔽寄存器

这些寄存器通过MSR/MRS指令访问,没有内存映射地址

1. PRIMASK

位[0]:中断屏蔽位

  • 0:允许所有可屏蔽中断(默认)
  • 1 :禁止所有可屏蔽中断
    • 相当于将当前优先级提升到0(最高优先级)
    • 不影响NMI和硬错误
      使用场景
  • 保护临界区代码不被中断打断
  • 短时间的原子操作
    快速设置指令
assembly 复制代码
CPSID I    ; 设置PRIMASK=1,禁止中断(关中断)
CPSIE I    ; 清除PRIMASK=0,允许中断(开中断)
2. FAULTMASK

位[0]:异常屏蔽位

  • 0:允许所有异常(默认)
  • 1 :禁止所有可屏蔽异常
    • 相当于将当前优先级提升到-1
    • 只有NMI可以响应
      使用场景
  • 在错误处理程序中防止其他异常干扰
  • 调试时隔离错误
    快速设置指令
assembly 复制代码
CPSID F    ; 设置FAULTMASK=1
CPSIE F    ; 清除FAULTMASK=0
3. BASEPRI

位[7:0]:优先级屏蔽阈值

  • 0:不屏蔽任何中断(默认)
  • 非0值n :屏蔽优先级号 ≥ n的所有中断
    • 注意:优先级数值越小优先级越高
    • 例如:BASEPRI=0x40,则优先级号0x40-0xFF的中断被屏蔽
    • 优先级号0x00-0x3F的中断仍可响应
      使用场景
  • 部分屏蔽中断,允许高优先级中断
  • 比PRIMASK更精细的控制
    示例
assembly 复制代码
; 屏蔽优先级低于0x60的所有中断(0x60-0xFF)
MOV R0, #0x60
MSR BASEPRI, R0

; 恢复所有中断
MOV R0, #0x00
MSR BASEPRI, R0

控制寄存器(CONTROL)

位域详解

  • nPRIV(位0) :特权级别控制
    • 0 :特权模式(默认)
      • 可以访问所有资源
      • 可以执行所有指令
      • 可以访问所有特殊寄存器
    • 1 :用户模式(非特权)
      • 受限的指令集
      • 不能访问某些系统寄存器
      • 不能修改中断配置
  • SPSEL(位1) :堆栈指针选择
    • 0 :使用主堆栈指针MSP(默认)
      • Handler模式总是使用MSP
      • 线程模式可选择使用MSP或PSP
    • 1 :使用进程堆栈指针PSP
      • 仅在线程模式下有效
  • FPCA(位2) :浮点上下文激活
    • 在Cortex-M3中为保留位(总是0)
    • 在Cortex-M4/M7中用于浮点单元
      模式切换规则
  1. 从特权模式进入用户模式

    assembly 复制代码
    ; 需要在特权模式下设置CONTROL
    MRS R0, CONTROL
    ORR R0, R0, #0x01    ; 设置用户模式
    MSR CONTROL, R0
    ISB                  ; 指令同步屏障
  2. 从用户模式返回特权模式

    • 只能通过触发异常(如SVC指令)
    • 异常处理程序运行在特权模式
    • 异常返回时可通过修改LR值选择返回模式
      堆栈指针使用规则
  • 异常入口:自动保存到当前使用的SP(可能是MSP或PSP)
  • 异常处理:总是使用MSP
  • 异常返回:根据EXC_RETURN值决定使用哪个SP

MRS/MSR指令

指令格式
assembly 复制代码
MRS <Rd>, <special_reg>    ; 从特殊寄存器读到通用寄存器
MSR <special_reg>, <Rn>    ; 从通用寄存器写到特殊寄存器
特殊寄存器名称
assembly 复制代码
; 状态寄存器
APSR, IPSR, EPSR, PSR, IEPSR, IAPSR, EAPSR

; 屏蔽寄存器  
PRIMASK, FAULTMASK, BASEPRI

; 控制寄存器
CONTROL
示例代码
assembly 复制代码
; 读取当前异常编号
MRS R0, IPSR            ; R0 = 当前异常编号

; 检查是否在中断中
MRS R0, IPSR
CMP R0, #0
BNE In_Interrupt

; 进入临界区(关中断)
MRS R0, PRIMASK
PUSH {R0}               ; 保存旧PRIMASK
CPSID I                 ; PRIMASK=1,禁止中断
; ... 临界区代码 ...
POP {R0}
MSR PRIMASK, R0         ; 恢复PRIMASK

; 切换到用户模式
MRS R0, CONTROL
ORR R0, R0, #0x01
MSR CONTROL, R0
ISB                     ; 确保指令流同步

; 切换到进程堆栈
MRS R0, CONTROL
ORR R0, R0, #0x02
MSR CONTROL, R0

这里我们使用比喻来加深印象
比喻一:老师监考教室

把特殊寄存器比作一个老师监考时的管理工具
xPSR - 老师的监考状态面板
APSR区域:考试纪律状态灯

  • N灯:有学生作弊嫌疑(负面行为)
  • Z灯:全班安静无声(零噪音)
  • C灯:有学生传递纸条(信息传递中)
  • V灯:考试时间快到了(时间溢出)
  • Q灯:考场温度过高(达到极限)

IPSR区域:老师当前处理的事务

  • 0:正常巡视监考
  • 2:校长突然闯入(NMI)
  • 3:严重违纪事件(硬错误)
  • 4:学生坐错位置(内存错误)
  • 5:试卷印刷错误(总线错误)
  • 6:学生违规用笔(用法错误)
  • 11:学生举手提问(SVCall)
  • 14:交卷时间到了(PendSV)
  • 15:考试剩余时间提醒(SysTick)

EPSR区域:监考规则状态

  • T灯:必须常亮(老师在场监督)
  • 其他显示:正在进行的多步骤处理(如调查作弊的进度)

优先级屏蔽寄存器 - 老师注意力过滤器

  • PRIMASK开关 :普通消息免打扰
    • 关(0):留意所有学生动静
    • 开(1):暂时不理睬任何小动作
    • 使用场景:处理严重作弊时,暂时忽略其他小声议论
  • FAULTMASK开关 :紧急情况专注模式
    • 关(0):处理所有违纪事件
    • 开(1):只处理最紧急事件(如打架),其他一律不管
    • 使用场景:考场发生冲突时,只关注最危险情况
  • BASEPRI旋钮 :违纪级别过滤器
    • 旋到0:处理所有违纪(从说话到作弊)
    • 旋到3:只处理中等以上违纪(如抄袭)
    • 旋到7:只处理严重违纪(如打架)
    • 使用场景:考试快结束时,只关注严重问题

CONTROL寄存器 - 老师身份与站位控制

  • nPRIV开关 :老师身份切换
    • 特权模式(0) :正式监考老师
      • 可以收试卷
      • 可以判违纪
      • 可以调整座位
    • 用户模式(1) :实习老师
      • 只能巡视
      • 不能处理违纪
      • 需要正式老师授权才能执行关键操作
  • SPSEL开关 :老师站位选择
    • 讲台位置(0) :站在讲台(主堆栈)
      • 全局视野
      • 处理紧急情况
    • 教室后排(1) :站在教室后面(进程堆栈)
      • 日常巡视位置
      • 观察学生状态

监考场景示例

场景:期末考试监考

1. 正常监考状态

  • 老师面板显示:IPSR=0(正常巡视)
  • 身份:正式老师(nPRIV=0)
  • 站位:教室后面(SPSEL=1)
  • 注意力:关注所有学生(PRIMASK=0)

2. 处理学生提问

  • 学生A举手提问(中断请求)
  • 老师查看当前事务:IPSR=11(学生提问)
  • 老师走到学生旁边处理(响应中断)
  • 其他学生的小动作暂时忽略(自动屏蔽低优先级)

3. 发现作弊事件

  • 学生B作弊(总线错误异常)
    • 面板显示IPSR=5
    • 老师立即进入专注模式(FAULTMASK=1,只关注严重问题)
    • 老师快速走向讲台(SPSEL=0,切换主视野位置)
    • 处理作弊事件,记录违纪

4. 考试时间管理

  • 剩余10分钟提醒(SysTick异常)
    • 面板显示IPSR=15
    • 老师宣布:"还有10分钟"
    • 调整注意力过滤器(设置BASEPRI=3,只关注严重问题)

5. 交卷流程

  • 考试结束铃响(PendSV异常)
    • 面板显示IPSR=14
    • 老师站在讲台(使用主堆栈)
    • 指挥收卷流程
    • 实习老师协助(用户模式任务)

6. 意外情况处理

  • 突然停电(硬错误)
    • 面板显示IPSR=3
    • 老师启动最高级别响应
    • 维持考场秩序
    • 必要时终止考试(系统复位)

比喻二:汽车驾驶控制系统

将特殊寄存器比作汽车的驾驶控制系统

xPSR - 汽车仪表盘综合显示屏
APSR区域:行驶状态指示灯

  • N灯:下坡指示灯(负坡度)
  • Z灯:零速度指示灯(停车)
  • C灯:牵引力控制灯(打滑时亮起)
  • V灯:超速警告灯(超出安全速度)
  • Q灯 :发动机过热警告(达到温度极限)
    IPSR区域:当前驾驶模式显示
  • 0:正常驾驶模式
  • 1:紧急启动模式(复位)
  • 2:强制接管模式(NMI)
  • 3:系统故障模式(硬错误)
  • 4:导航错误(内存错误)
  • 5:通信错误(总线错误)
  • 6:操作错误(用法错误)
  • 11:语音指令模式(SVCall)
  • 14:自动驾驶交接(PendSV)
  • 15 :巡航定时(SysTick)
    EPSR区域:系统状态显示
  • T灯:必须常亮(手动驾驶模式就绪)
  • ICI/IT显示:多步骤操作进度(如自动泊车步骤)

优先级屏蔽寄存器 - 驾驶专注度控制

  • PRIMASK开关 :电话免打扰开关
    • 关闭(0):接听所有来电
    • 打开(1):拒接所有电话
    • 使用场景:高速超车时,避免电话干扰
  • FAULTMASK开关 :全系统静音开关
    • 关闭(0):所有警告音正常
    • 打开(1):只保留碰撞警告,其他全部静音
    • 使用场景:车辆严重故障时,避免其他警告分散注意力
  • BASEPRI旋钮 :警告重要性过滤
    • 旋到0:显示所有警告
    • 旋到1:只显示重要警告(如油量低)
    • 旋到2:只显示紧急警告(如发动机故障)
    • 使用场景:城市驾驶时过滤不重要的提醒

CONTROL寄存器 - 驾驶权限控制面板

  • nPRIV开关 :驾驶权限开关
    • 特权模式(0) :教练模式
      • 可以操作所有功能
      • 可以修改车辆设置
      • 可以接管控制
    • 用户模式(1) :学员模式
      • 只能使用基本功能
      • 不能修改设置
      • 需要教练授权才能执行特殊操作
  • SPSEL开关 :座椅位置选择
    • 主驾驶座(0) :使用教练座椅(MSP)
      • 视野好,控制全面
      • 紧急情况下使用
    • 副驾驶座(1) :使用学员座椅(PSP)
      • 日常驾驶使用
      • 受限制的控制权

MRS/MSR指令 - 专用控制指令

就像驾校的专用教学口令

  • MRS :学员报告当前状态

    assembly 复制代码
    "报告教练,当前车速120,转速3000"  ← MRS读取状态
  • MSR :教练下达控制指令

    assembly 复制代码
    "切换到手动挡,关闭音响"  ← MSR写入控制

只有教练(特权模式) 可以下达MSR指令,学员(用户模式)只能报告状态。

驾驶场景比喻
场景:驾校训练课程

  1. 正常驾驶(线程模式)
    • 仪表盘显示:IPSR=0(正常驾驶)

    • 权限:学员模式(nPRIV=1)

    • 座椅:副驾驶座(SPSEL=1,PSP)

    • 电话:正常接听(PRIMASK=0)
      紧急情况处理

    • 突发故障 :发动机警告灯亮(总线错误异常)

      • 仪表盘IPSR显示异常编号5
      • 教练立即按下FAULTMASK(只关注最紧急的碰撞警告)
      • 教练切换回主驾驶座(切换到MSP)
    • 处理过程

      assembly 复制代码
      ; 进入错误处理程序
      CPSID F          ; FAULTMASK=1,屏蔽其他干扰
      MSR CONTROL, #0  ; 切回特权模式+主堆栈
      ; 处理错误...
      CPSIE F          ; 恢复异常处理

多任务训练

  • BASEPRI过滤 :教练设置只显示重要警告

    assembly 复制代码
    MOV R0, #0x40
    MSR BASEPRI, R0  ; 忽略优先级低于0x40的警告
  • 临界区操作 :练习坡道起步

    assembly 复制代码
    MRS R0, PRIMASK
    PUSH {R0}
    CPSID I          ; 禁止所有中断(电话)
    ; 专注坡道起步操作...
    POP {R0}
    MSR PRIMASK, R0  ; 恢复中断设置

权限切换

  • 学员需要开启危险报警灯(需要特权):

    assembly 复制代码
    ; 学员模式下无法直接开启
    SVC #0           ; 调用系统服务(请求教练帮忙)
    ; 在SVC处理程序中(特权模式)开启报警灯

系统恢复

  • 车辆完全失控:

    assembly 复制代码
    ; 触发硬错误
    ; 在HardFault处理程序中:
    LDR R0, =0xE000ED0C
    LDR R1, =0x05FA0004  ; VECTKEY + SYSRESETREQ
    STR R1, [R0]         ; 请求系统复位(重启车辆)


总结

寄存器类别 配置阶段(初始化) 运行阶段(动态) 诊断阶段(调试) 比喻角色
NVIC_ISER/ICER 使能/禁用中断 动态调整中断使能 检查中断使能状态 医院挂号/停诊窗口
NVIC_ISPR/ICPR (通常不配置) 软件触发/清除中断 查看悬挂中断 候诊名单管理
SCB_VTOR 设置向量表位置 Bootloader跳转时重定位 确认当前向量表位置 飞行手册存放位置
PRIMASK/BASEPRI (通常为0) 临界区保护时设置 检查当前屏蔽状态 注意力过滤器
CONTROL 设置初始模式 任务切换时修改 确定当前模式 驾驶权限控制

我们使用比喻来梳理一下:

"智慧城市应急响应系统"总体框架

  1. 基础设施层(NVIC) :城市各区的应急服务站(消防、医疗、警察)
    • ISER/ICER:服务站值班表
    • IPR:事件优先级评估标准
    • IABR:正在处理的应急事件显示屏
  2. 指挥中心层(SCB) :城市应急指挥中心
    • ICSR:指挥中心大屏(显示当前和待处理事件)
    • VTOR:应急预案手册存放系统
    • AIRCR:应急响应规则制定委员会
  3. 计时与调度层(SysTick) :城市统一时间系统
    • 提供精确的时间基准
    • 驱动定期巡查和任务轮转
  4. 权限控制层(特殊寄存器) :应急人员身份与权限
    • xPSR:当前执行人员的状态徽章
    • PRIMASK/FAULTMASK:紧急情况下的通信过滤
    • CONTROL:人员身份牌(指挥员/执行员)
相关推荐
myloveasuka2 小时前
MREQ̅ 信号
笔记·算法·计算机组成原理
andyweike2 小时前
Android笔记2
笔记
学工科的皮皮志^_^2 小时前
以太网PHY芯片学习RTF8211
经验分享·嵌入式硬件·学习·以太网·phy
沐欣工作室_lvyiyi2 小时前
基于单片机的直流伺服电机控制器设计与仿真(论文+源码)
单片机·嵌入式硬件·毕业设计·直流伺服电机
求真求知的糖葫芦2 小时前
微波工程2.3节学习笔记(自用)
笔记·学习·射频工程
清风6666662 小时前
基于单片机的智能传送带自动计数与数据管理系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
charlie1145141912 小时前
嵌入式C++开发——RAII 在驱动 / 外设管理中的应用
开发语言·c++·笔记·嵌入式开发·工程实践
麒qiqi2 小时前
嵌入式定时器核心解析:51 单片机 / IMX6ULL (EPIT/GPT) 原理与实战
单片机·嵌入式硬件·gpt
蓬荜生灰2 小时前
STM32(7)-- GPIO输出,寄存器版
stm32·单片机·嵌入式硬件