个人学习的笔记,希望帮助能到和我一样阅读Cortex-M3权威指南Cn遇到困难的人。
强烈建议先阅读Cortex-M3权威指南Cn第八章在来观看笔记
在cortex m3 中,中断(异常)常用寄存器
在Cortex-M3中,异常和中断的管理涉及多个寄存器,主要属于嵌套向量中断控制器(NVIC)和系统控制块(SCB)。以下是一些重要的寄存器及其具体作用的详细描述:
一、 NVIC寄存器组(地址范围:0xE000E100 - 0xE000E4FF)
- 中断使能寄存器(Interrupt Enable Registers)
- NVIC_ISER0 - NVIC_ISER7(Interrupt Set-Enable Registers):每个位对应一个中断,写1到某位可使能相应的中断。这些寄存器用于使能中断。
- NVIC_ICER0 - NVIC_ICER7(Interrupt Clear-Enable Registers):每个位对应一个中断,写1到某位可禁用相应的中断。这些寄存器用于禁用中断。
- 中断悬挂寄存器(Interrupt Pending Registers)
- NVIC_ISPR0 - NVIC_ISPR7(Interrupt Set-Pending Registers):每个位对应一个中断,写1到某位可以将相应中断的状态设置为悬挂(等待处理)。
- NVIC_ICPR0 - NVIC_ICPR7(Interrupt Clear-Pending Registers):每个位对应一个中断,写1到某位可以清除相应中断的悬挂状态。
- 中断活动状态寄存器(Interrupt Active Status Registers)
- NVIC_IABR0 - NVIC_IABR7(Interrupt Active Bit Registers):每个位对应一个中断,为1表示相应的中断正在被处理(活动状态)。这些寄存器是只读的。
- 中断优先级寄存器(Interrupt Priority Registers)
- NVIC_IPR0 - NVIC_IPR31(Interrupt Priority Registers):每个中断对应一个8位的优先级字段(但通常只使用高4位)。这些寄存器用于设置每个中断的优先级,优先级数值越小,优先级越高。
- 软件触发中断寄存器(Software Trigger Interrupt Register)
- NVIC_STIR(Software Trigger Interrupt Register):通过向此寄存器写入中断编号,可以软件触发相应的中断。
二、 SCB寄存器组(地址范围:0xE000ED00 - 0xE000ED3F)
- 中断控制与状态寄存器(Interrupt Control and State Register)
- SCB_ICSR (Interrupt Control and State Register):提供异常处理的控制和状态信息。主要位段包括:
- VECTACTIVE:当前正在处理的中断或异常的编号。
- VECTPENDING:当前悬挂的最高优先级中断或异常的编号。
- ISRPENDING:表示是否有外部中断处于悬挂状态。
- PENDSTSET, PENDSTCLR:分别用于悬挂和清除SysTick异常。
- PENDSVSET, PENDSVCLR:分别用于悬挂和清除PendSV异常。
- NMIPENDSET:NMI(不可屏蔽中断)的悬挂位。
- SCB_ICSR (Interrupt Control and State Register):提供异常处理的控制和状态信息。主要位段包括:
- 向量表偏移寄存器(Vector Table Offset Register)
- SCB_VTOR(Vector Table Offset Register):指定异常向量表的起始地址。复位后为0,向量表位于0地址。可以将其重定位到其他地址(如RAM或Flash的特定区域)。
- 应用中断与复位控制寄存器(Application Interrupt and Reset Control Register)
- SCB_AIRCR (Application Interrupt and Reset Control Register):用于控制中断优先级分组和系统复位。主要位段包括:
- PRIGROUP:用于设置中断优先级分组(即将一个8位的优先级寄存器划分为抢占优先级和子优先级两部分)。
- SYSRESETREQ:写1可请求系统复位。
- VECTCLRACTIVE:在调试时用于清除活动的中断状态。
- ENDIANNESS:指示处理器的字节序(只读)。
- SCB_AIRCR (Application Interrupt and Reset Control Register):用于控制中断优先级分组和系统复位。主要位段包括:
- 系统异常优先级寄存器(System Handler Priority Registers)
- SCB_SHPR1 - SCB_SHPR3(System Handler Priority Registers):用于设置系统异常的优先级。系统异常(如SVCall、PendSV、SysTick等)的优先级可以通过这些寄存器设置。
- 系统异常控制与状态寄存器(System Handler Control and State Register)
- SCB_SHCSR(System Handler Control and State Register):用于使能系统异常(如用法错误、总线错误、内存管理错误等)以及查询其状态。例如,可以查询当前是否有悬挂的系统异常。
三、 SysTick寄存器(系统定时器,属于系统异常)
- SysTick控制和状态寄存器(SysTick Control and Status Register)
- SysTick_CTRL :控制SysTick定时器的行为和状态。主要位包括:
- ENABLE:使能SysTick定时器。
- TICKINT:使能SysTick中断(当计数器减到0时产生异常)。
- CLKSOURCE:选择时钟源(系统时钟或外部参考时钟)。
- COUNTFLAG:当计数器减到0时置1,读取该寄存器后清零。
- SysTick_CTRL :控制SysTick定时器的行为和状态。主要位包括:
- SysTick重载值寄存器(SysTick Reload Value Register)
- SysTick_LOAD:设置SysTick定时器重载值。当计数器减到0后,下次计数将从该值开始。
- SysTick当前值寄存器(SysTick Current Value Register)
- SysTick_VAL:读取当前计数器的值。写操作会清零该寄存器,同时清除COUNTFLAG标志。
四、 特殊寄存器(通过MRS/MSR指令访问)
- 程序状态寄存器(Program Status Register)
- xPSR:组合了应用程序状态寄存器(APSR)、中断状态寄存器(IPSR)和执行状态寄存器(EPSR)。其中IPSR包含了当前正在处理的中断或异常的编号。
- 优先级屏蔽寄存器(Priority Mask Registers)
- PRIMASK:写1可禁止所有可屏蔽中断(即设置为最高优先级,阻止中断)。
- FAULTMASK:写1可禁止所有中断和异常(除了NMI)。
- BASEPRI:设置一个优先级阈值,只有优先级高于此阈值的中断才能被响应。
- 控制寄存器(Control Register)
- CONTROL:控制处理器的操作模式和堆栈选择。例如,可以切换为使用进程堆栈(PSP)而不是主堆栈(MSP)。
在cortex m3 中,NVIC寄存器组
1. 中断使能寄存器(Interrupt Enable Registers)
地址范围 :0xE000E100 - 0xE000E11C
- NVIC_ISER0 :
0xE000E100- 控制中断0-31 - NVIC_ISER1 :
0xE000E104- 控制中断32-63 - NVIC_ISER2 :
0xE000E108- 控制中断64-95 - ... 以此类推,直到 NVIC_ISER7 :
0xE000E11C- 控制中断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)
详细功能: - 软件模拟硬件中断
- 用于测试中断服务程序
- 任务间通信和同步
- 调试时手动触发中断流程
典型中断处理过程:
- 中断发生 :
- 硬件自动设置NVIC_ISPR对应位(中断悬挂)
- 中断响应前 :
- NVIC比较所有悬挂中断的优先级
- 选择最高优先级中断准备响应
- 中断响应 :
- 硬件清除NVIC_ISPR对应位(清除悬挂)
- 硬件设置NVIC_IABR对应位(标记为活动)
- 处理器跳转到中断服务程序
- 中断处理中 :
- NVIC_IABR保持为1
- 可被更高优先级中断抢占
- 中断返回 :
- 硬件清除NVIC_IABR对应位
- 如果有其他悬挂中断,继续处理
这里使用比喻来方便我们理解:
比喻:医院急诊室系统:
将NVIC寄存器组比作一个现代化医院急诊室管理系统 :
1. ISER/ICER - 挂号窗口与停诊通知
- ISER(挂号窗口):病人(中断)在此登记,获得就诊资格。登记后,医院(处理器)才会关注这个病人
- ICER (停诊通知):取消某类病人的就诊资格,但已经挂号的病人仍在等待
2. ISPR/ICPR - 候诊名单管理 - ISPR(新增候诊):新病人到达或医生手动添加病人到候诊名单
- ICPR (移除名单):病人放弃等待、转院或误登记时从名单移除
3. IABR - 诊室状态显示屏 - 只读显示屏:显示正在接受治疗的病人
- 每个诊室(处理器核心)一次只治疗一个病人
- 显示屏实时更新,病人开始治疗时亮灯,离开时灭灯
4. IPR0-IPR31 - 病情分级卡 - 每个病人有一张分级卡:记录病情严重程度(优先级)
- 分级规则 (PRIGROUP):医院统一规定如何解读分级卡
- 例如:前4位表示紧急程度(能否插队),后4位表示同类病人的细微差别
- 分诊台 (NVIC比较逻辑):持续扫描候诊名单,选择病情最紧急的病人
5. STIR - 医生紧急呼叫按钮 - 医生手动触发:当需要立即处理某个特定病例时使用
- 前提条件:病人必须已在系统登记(中断已使能)
- 使用场景:紧急会诊、测试医疗流程、内部协调
系统工作流程比喻:
场景:心脏病突发患者(高优先级中断)和感冒患者(低优先级中断)同时到达
- 登记:两者都在ISER挂号窗口登记(中断使能)
- 候诊:ISPR自动将两人加入候诊名单(中断悬挂)
- 分诊 :
- 分诊台(NVIC)读取两人的病情分级卡(IPR)
- 心脏病:优先级0x10(高)
- 感冒:优先级0xE0(低)
- 选择心脏病患者优先处理
- 治疗 :
- IABR显示屏显示"心脏病治疗中"
- 感冒患者继续在候诊名单(ISPR)等待
- 特殊情况 :
- 如果心脏病治疗中,来了更紧急的枪伤患者(更高优先级):
- 心脏病治疗暂停(被抢占)
- 枪伤患者进入诊室,IABR更新显示
- 如果感冒患者等不及离开:通过ICPR从候诊名单移除
- 如果心脏病治疗中,来了更紧急的枪伤患者(更高优先级):
- 医生主动呼叫 :
- 住院部需要急诊会诊:医生按下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字节
重定位场景:
- 从RAM运行程序:向量表复制到RAM,VTOR指向RAM地址
- 引导加载程序:引导程序在Flash,应用程序在另一Flash区域
- 多任务系统 :不同任务有自己的异常处理程序
读写规则:
- 可读写,但通常只在系统初始化时设置
- 修改前建议禁用全局中断
- 地址必须满足对齐要求
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_SHPR1 :
0xE000ED18 - SCB_SHPR2 :
0x0000ED1C - SCB_SHPR3 :
0xE000ED20
详细映射:
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可清除悬挂状态
- 活动状态位:只读,由硬件自动管理
异常处理流程示例:
- 异常发生 :MemManage错误(系统异常4)
- 如果MEMFAULTENA=1,则进入MemManage异常
- 如果MEMFAULTENA=0,则升级为HardFault(异常3)
- 状态更新 :
- SCB_ICSR.VECTACTIVE = 4
- SCB_SHCSR.MEMFAULTACT = 1
- 优先级比较 :
- 使用SCB_SHPR1配置的MemManage优先级
- 与PRIGROUP设置的分组规则结合
- 异常返回 :
- SCB_SHCSR.MEMFAULTACT = 0
- 根据SCB_ICSR.RETTOBASE决定返回路径
这里使用几个比喻来方便我们理解:
比喻一:系统工作流程
想象一个大型工厂的操作系统调度中心:
- 正常运行时 :
- 调度中心大屏(ICSR)显示VECTACTIVE为0,表示没有异常,工厂正常生产。
- 向量表仓库(VTOR)指向默认位置,存储着各种异常处理程序地址。
- 发生外部中断 :
- 流水线发出故障信号(外部中断),ISRPENDING灯亮起。
- 大屏显示VECTPENDING为该故障的工号。
- 调度中心根据优先级比较,如果当前没有更高优先级的任务,则开始处理此故障。
- 系统调用 :
- 工人发出系统调用请求(SVCall),调度中心设置SVCall的悬挂状态。
- 由于SVCall优先级较高(通过SHPR2设置),调度中心暂停当前工作,处理系统调用。
- 任务切换 :
- 系统定时器(SysTick)发出时间片用完的信号,调度中心通过PENDSTSET悬挂SysTick异常。
- 调度中心决定进行任务切换,于是通过PENDSVSET悬挂PendSV异常。
- 由于PendSV的优先级被设为最低(通过SHPR3),它会等到其他紧急任务都处理完后才执行,从而安全地进行任务切换。
- 系统错误处理 :
- 如果发生内存访问错误(MemManage Fault),且使能了该异常(SHCSR中MEMFAULTENA为1),则错误处理程序被调用。
- 错误处理期间,大屏显示MEMFAULTACT为1,表示正在处理内存管理错误。
- 系统复位 :
- 工厂出现严重故障,无法通过常规手段恢复。调度员按下紧急复位按钮(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)
- 各紧急类型飞机工作中
空域管理场景
场景:繁忙国际机场的空域管理
- 正常运作 :
- 主显示屏(ICSR)显示VECTACTIVE=0,空域正常
- 飞行手册(VTOR)在主控室标准位置
- 空域规则(AIRCR)设定为"军用优先"模式(PRIGROUP=4)
- 紧急情况发生 :
- 医疗救援机报告紧急情况(MemManage错误)
- 如果医疗系统开关(MEMFAULTENA)打开:
- 医疗救援机按SHPR1登记优先级响应
- 状态板亮起"医疗救援工作中"绿灯(MEMFAULTACT=1)
- 如果开关关闭:直接触发最高紧急响应
- 多任务处理 :
- 塔台发出调度指令(SVCall)
- 定期巡逻机时间到(SysTick)
- 航班需要交接(PendSV)
- 管制中心根据SHPR2/SHPR3的优先级安排:
- 塔台指令最先响应(高优先级)
- 医疗救援同时进行
- 定期巡逻机随后
- 航班交接最后(PendSV设为最低优先级)
- 空域重配置 :
- 夜间模式:将飞行手册移到快速存取室(VTOR指向RAM)
- 调整规则:改为"民航优先"模式(修改PRIGROUP)
- 关闭部分监控系统(修改SHCSR使能位)
- 灾难恢复 :
- 空域完全失控:管制员按下紧急清空按钮(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)
- 以及各突发事件处理中
学校管理场景
- 正常上课 :
- 显示屏显示VECTACTIVE=0(课间休息)。
- 课程表在教务处文件柜(VTOR默认地址)。
- 教学规则设定为"主科优先"(PRIGROUP=4)。
- 突发事件 :
- 有学生生病(MemManage错误)。
- 如果学生生病处理系统开关打开(MEMFAULTENA=1):
- 按照SHPR1登记的优先级处理(比如先送医务室)。
- 监控板亮起"学生生病处理中"绿灯(MEMFAULTACT=1)。
- 如果开关关闭,则直接升级为紧急事件(HardFault)。
- 多任务处理 :
- 教务处广播通知(SVCall)。
- 课间操时间到(SysTick)。
- 需要调课(PendSV)。
- 教务处根据SHPR2/SHPR3的优先级安排:
- 先处理广播通知(高优先级)。
- 同时处理学生生病事件。
- 然后做课间操。
- 最后处理调课(PendSV通常设最低优先级)。
- 教学调整 :
- 期末考试期间,将课程表复制到教师办公室(VTOR重定位到RAM)以便快速调整。
- 调整规则为"副科也可打断主科"(修改PRIGROUP)。
- 关闭学生违规监控系统(修改SHCSR使能位)。
- 紧急情况 :
- 学校出现严重安全威胁,教务处按下全校紧急放学按钮(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计数一次
- 系统时钟 = 72MHz时:
- COUNTFLAG(位16) :计数到0标志位
- 只读位
- 0 = 计数器未计数到0
- 1 = 计数器已计数到0(自上次读取该寄存器后)
- 特殊行为:读取该寄存器时自动清零
- 用途 :轮询方式检测定时时间到达(不使用中断时)
读写规则:
- 位0-2可读写
- 位16只读,读取时自动清零
- 其他位保留,写0,读为0
SysTick重载值寄存器(SysTick_LOAD)
地址 :0xE000E014
格式:
- 位[23:0]:重载值(RELOAD)
- 位[31:24] :保留,必须为0
功能详解: - 作用:设置计数器递减的起始值
- 工作流程 :
- 计数器从LOAD值开始递减
- 减到0时,如果ENABLE=1,自动重载LOAD值并继续
- 减到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值重新开始递减(如果使能了定时器)
- 用途 :
- 读取当前剩余计数值
- 软件清零计数器
- 同步计数器(在某些应用中)
读写规则:
- 可读写,24位有效
- 写入操作具有"副作用"(清零计数器并清除COUNTFLAG)
SysTick异常详解
异常编号 :15(系统异常中最后一个)
异常优先级 :通过SCB_SHPR3寄存器的PRI_15字段(位31:24)设置
为什么要有SysTick异常?
- 操作系统时基:为RTOS提供精确的定时心跳
- 任务调度:驱动任务时间片轮转
- 延时函数:实现精确的软件延时
- 性能测量:测量代码执行时间
- 系统监控:超时检测、看门狗等
- 独立于外设定时器:不依赖芯片特定的定时器外设,提高可移植性
与其他定时器的区别:
- 内核集成:SysTick是Cortex-M3内核的一部分,所有兼容芯片都有
- 简化编程:寄存器少,配置简单
- 确定行为:不受芯片厂商实现差异影响
这里我们使用比喻来了解他:
比喻一:心脏与脉搏
将SysTick比作人体的心脏和脉搏系统:
SysTick_CTRL - 心脏控制中枢
- ENABLE开关 :心脏起搏器开关
- 打开:心脏开始跳动
- 关闭:心脏停止
- TICKINT开关 :神经系统连接开关
- 打开:每次心跳向大脑发送信号
- 关闭:心跳但不通知大脑
- CLKSOURCE选择 :心跳节奏选择
- 快速节奏:正常心跳(系统时钟)
- 慢速节奏:休息时心跳(外部时钟/8)
- COUNTFLAG标志 :脉搏检测点
- 每次心跳到最低点时亮起
- 医生(软件)检查后自动熄灭
SysTick_LOAD - 心跳间隔设置
- 设置值 :决定两次心跳之间的时间间隔
- 比如设置为每分钟60次(LOAD对应值)
- 设置值越大,心跳越慢
- 设置值越小,心跳越快
SysTick_VAL - 当前心跳状态
- 读操作 :听诊器听心跳
- 听到当前心跳到什么位置了
- 还有多久到下一次心跳
- 写操作 :心脏电击复位
- 任何电击都会让心跳立即归零
- 然后按照设定间隔重新开始
人体系统工作流程:
- 系统启动 (身体苏醒):
- 医生(操作系统)设置心跳间隔(LOAD=71999,1ms一次)
- 打开心脏起搏器(ENABLE=1)
- 连接神经系统(TICKINT=1)
- 选择正常节奏(CLKSOURCE=1,系统时钟)
- 正常心跳 :
- 心脏从LOAD值开始递减(心跳从高点向低点)
- 每次到0(心跳完成):
- 自动重载LOAD值(准备下一次心跳)
- 向大脑发送信号(SysTick异常)
- COUNTFLAG亮起(脉搏点)
- 大脑响应 (中断服务程序):
- 大脑收到心跳信号
- 检查身体各部位状态(调度器检查任务)
- 决定是否切换活动(任务切换)
- 更新身体时钟(系统时间累加)
- 特殊情况 :
- 检查脉搏:医生手动检查COUNTFLAG(轮询方式)
- 调整心率:修改LOAD值改变心跳间隔
- 心脏复位:写入VAL重置心跳周期
- 心脏停跳:关闭ENABLE(休眠模式)
比喻二(RTOS中):工厂流水线的节拍器
在RTOS中,SysTick就像工厂流水线的节拍器 ,控制整个生产节奏:
为什么需要独立的节拍器(SysTick)?
- 统一节奏 :
- 所有生产线(任务)使用相同的节拍
- 保证生产(任务执行)的同步性
- 避免不同产线(外设定时器)节奏不一致
- 精确调度 :
- 时间片轮转 :每个工人(任务)工作固定节拍数
- 节拍器响 → 切换工人
- 保证每个工人都有公平的工作时间
- 优先级调度 :
- 高优先级任务:可以占用多个节拍
- 低优先级任务:等待空闲节拍
- 时间片轮转 :每个工人(任务)工作固定节拍数
- 系统时间基准 :
- 记录工厂运行了多久(系统运行时间)
- 计算产品生产时间(任务执行时间)
- 安排生产计划(定时任务)
- 延时控制 :
- 工人休息固定节拍数(任务延时)
- 等待物料到达的超时检测(同步超时)
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(当前任务时间片用完 || 有更高优先级任务就绪) {
触发任务调度();
}
}
工厂节拍器场景 :
场景:汽车装配工厂有三条生产线(任务):
- 发动机装配线 (高优先级任务):
- 每10个节拍必须完成一台发动机
- 节拍器每响一次,完成一部分工作
- 车身装配线 (中优先级任务):
- 每20个节拍完成一个车身
- 在发动机线空闲时获得更多节拍
- 喷漆线 (低优先级任务):
- 每30个节拍完成喷漆
- 只有前两条线都空闲时才工作
节拍器(SysTick)工作:
- 节拍间隔:1秒(LOAD值决定)
- 每响一次 :
- 生产线主任(调度器)检查各线进度
- 决定下一节拍哪个线工作
- 记录总生产时间
优势:
- 公平性:每个任务按时间片工作
- 响应性:高优先级任务及时响应
- 可预测性:系统行为时间可预测
- 可移植性 :换工厂(芯片)只需调整节拍间隔(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 :用户模式(非特权)
- 受限的指令集
- 不能访问某些系统寄存器
- 不能修改中断配置
- 0 :特权模式(默认)
- SPSEL(位1) :堆栈指针选择
- 0 :使用主堆栈指针MSP(默认)
- Handler模式总是使用MSP
- 线程模式可选择使用MSP或PSP
- 1 :使用进程堆栈指针PSP
- 仅在线程模式下有效
- 0 :使用主堆栈指针MSP(默认)
- FPCA(位2) :浮点上下文激活
- 在Cortex-M3中为保留位(总是0)
- 在Cortex-M4/M7中用于浮点单元
模式切换规则:
-
从特权模式进入用户模式 :
assembly; 需要在特权模式下设置CONTROL MRS R0, CONTROL ORR R0, R0, #0x01 ; 设置用户模式 MSR CONTROL, R0 ISB ; 指令同步屏障 -
从用户模式返回特权模式 :
- 只能通过触发异常(如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) :实习老师
- 只能巡视
- 不能处理违纪
- 需要正式老师授权才能执行关键操作
- 特权模式(0) :正式监考老师
- SPSEL开关 :老师站位选择
- 讲台位置(0) :站在讲台(主堆栈)
- 全局视野
- 处理紧急情况
- 教室后排(1) :站在教室后面(进程堆栈)
- 日常巡视位置
- 观察学生状态
- 讲台位置(0) :站在讲台(主堆栈)
监考场景示例
场景:期末考试监考
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) :学员模式
- 只能使用基本功能
- 不能修改设置
- 需要教练授权才能执行特殊操作
- 特权模式(0) :教练模式
- SPSEL开关 :座椅位置选择
- 主驾驶座(0) :使用教练座椅(MSP)
- 视野好,控制全面
- 紧急情况下使用
- 副驾驶座(1) :使用学员座椅(PSP)
- 日常驾驶使用
- 受限制的控制权
- 主驾驶座(0) :使用教练座椅(MSP)
MRS/MSR指令 - 专用控制指令
就像驾校的专用教学口令:
-
MRS :学员报告当前状态
assembly"报告教练,当前车速120,转速3000" ← MRS读取状态 -
MSR :教练下达控制指令
assembly"切换到手动挡,关闭音响" ← MSR写入控制
只有教练(特权模式) 可以下达MSR指令,学员(用户模式)只能报告状态。
驾驶场景比喻
场景:驾校训练课程
- 正常驾驶(线程模式) :
-
仪表盘显示:IPSR=0(正常驾驶)
-
权限:学员模式(nPRIV=1)
-
座椅:副驾驶座(SPSEL=1,PSP)
-
电话:正常接听(PRIMASK=0)
紧急情况处理: -
突发故障 :发动机警告灯亮(总线错误异常)
- 仪表盘IPSR显示异常编号5
- 教练立即按下FAULTMASK(只关注最紧急的碰撞警告)
- 教练切换回主驾驶座(切换到MSP)
-
处理过程 :
assembly; 进入错误处理程序 CPSID F ; FAULTMASK=1,屏蔽其他干扰 MSR CONTROL, #0 ; 切回特权模式+主堆栈 ; 处理错误... CPSIE F ; 恢复异常处理
-
多任务训练:
-
BASEPRI过滤 :教练设置只显示重要警告
assemblyMOV R0, #0x40 MSR BASEPRI, R0 ; 忽略优先级低于0x40的警告 -
临界区操作 :练习坡道起步
assemblyMRS 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 | 设置初始模式 | 任务切换时修改 | 确定当前模式 | 驾驶权限控制 |
我们使用比喻来梳理一下:
"智慧城市应急响应系统"总体框架:
- 基础设施层(NVIC) :城市各区的应急服务站(消防、医疗、警察)
- ISER/ICER:服务站值班表
- IPR:事件优先级评估标准
- IABR:正在处理的应急事件显示屏
- 指挥中心层(SCB) :城市应急指挥中心
- ICSR:指挥中心大屏(显示当前和待处理事件)
- VTOR:应急预案手册存放系统
- AIRCR:应急响应规则制定委员会
- 计时与调度层(SysTick) :城市统一时间系统
- 提供精确的时间基准
- 驱动定期巡查和任务轮转
- 权限控制层(特殊寄存器) :应急人员身份与权限
- xPSR:当前执行人员的状态徽章
- PRIMASK/FAULTMASK:紧急情况下的通信过滤
- CONTROL:人员身份牌(指挥员/执行员)