// 本文部分内容来自网络
1. ARMv7-M与ARMv7-A/ARMv7-R和之间有什么区别?
Version 7 of the ARM® architecture or "ARMv7" comprises three profiles:
- A for Applications.
- R for Real-time.
- M for Microcontroller.
- 不支持ARM指令集(仅支持Thumb指令集);已扩展到同时支持16位和32位指令Thumb-2版本。
- 只有两种操作模式(线程(Thread )模式和处理程序(Handler )模式)。
- 不可配置,固定的默认内存映射(如在ARMv7-R中,但配置不同)。
- 可选内存保护单元(MPU)支持(ARMv7-R中需要)用于可配置内存映射(不支持与ARMv7-A类似的内存管理单元(MMU)支持)。
- 默认情况下不支持协处理器(除了为可选浮点扩展保留的协处理器10和11之外),例如,没有类似ARMv7-AR协处理器15的行为;所有的处理器配置,状态报告和控制寄存器都是内存映射的。
- 中断控制器(嵌套向量中断控制器NVIC)是处理器的一部分。
- NMI(不可屏蔽中断)。
- 状态在异常进入/返回时自动保存/恢复。
- 向量表包含地址,而不是指令。
- 异常处理程序可以很容易地用C进行编程
- Debug针对微控制器应用进行了优化。
- 另外,在ARMv7-M参考手册的修订版E之前,内部缓存是不允许的。
此外,A profile和R profile还提供了很多高级的功能和扩展,这些功能在ARMv7-M中不可用,例如:
- 高级SIMD扩展(以NEON™命名)。
- 性能监视器扩展(用于高级调试/性能分析)。
- 虚拟化扩展(用于虚拟平台支持)。
A profile还提供了安全扩展(以TrustZone®命名)。
向量表包含地址,而不是指令
CortexM处理器向量表中的数值是异常处理程序的32位地址,而不是跳转指令。
下面截图以CortexM0处理器 + Zephyr 操作系统为例,说明其向量表分布:
地址0: main stack起始地址(最高地址,msp初始值)
地址4: 0xffc8909-> __reset
地址8: 0xffc8965-> __nmi
地址C: 0xffc8809-> __hard_fault
......
地址2C: 0xffc8625-> __svc
......
地址38: 0xffc85B1-> __pendsv
......
地址40: 0xffc88D1-> _isr_wrapper
......
对应M0的异常处理模型:
(n = 31)
作为对比,以Cortex A9+Linux操作系统为例,其向量表中数值都是跳转指令:
8条跳转指令,分别对应处理器的8个异常:
复位、未定义指令、软中断SWI、指令预取中止(Prefetch Abort)、数据访问中止(Data Abort)、保留、普通中断(IRQ)、快速中断(FIQ)。
复位流程
复位状态后,Cortex M处理器做的第一件事就是读取下列两个32位整数的值:
1)从地址0x0000 0000 处取出MSP的初始值;
2)从地址0x0000 0004 处取出PC的初始值;
MSP得初始值必须是堆栈内存的末地址加1.举例来说:如果堆栈区域在0x20007C00~0x20007FFF之间,那么MSP的初始值就必须是0x20008000
Cortex M是在Thumb态下执行,所以向量表中的每个数值必须把LSB(最低位)置1(也就是奇数)。
操作模式与状态
Cortex-M处理器的CONTROL寄存器定义了:
- 栈指针的选择(主栈指针/进程栈指针)
- 线程模式的访问等级(特权/非特权)
nPRIV(第0位) 定义线程模式中的特权等级:该位为0时(默认),处理器会处于线程模式中的特权等级; 1时,则处于线程模式中的非特权等级
SPSEL(第1位) 定义栈指针的选择:该位为0时(默认),线程模式使用主栈指针(MSP); 1时,线程模式使用进程栈指针; 处理模式时,该位始终位0且对其的写操作会被忽略
- 复位以后默认CONTROL寄存器默认为0,说明启动以后处理器处于线程模式(默认),具有特权访问权限以及使用MSP.
- Cortex M0不支持非特权线程模式
xPSR,组合程序状态寄存器
xPSR寄存器
组合程序状态寄存器提供了程序执行信息和ALU(算数逻辑单元)标志,该寄存器由三个程序状态寄存器(PSR)组成,如上图:
- 应用程序状态寄存器(APSR)
- 中断程序状态寄存器(IPSR)
- 执行程序状态寄存器(EPSR)
APSR包含了ALU算数逻辑单元标志,位于xPSR最高4位,一般用于控制程序跳转:
- N表示负号标志
- Z表示零标志
- C表示进位或借位标志
- V表示溢出标志
IPSR包含了当前正在执行的中断服务程序(ISR)编号,Cortex-M0的每个异常中断都会由一个特定的中断编号(表示中断类型),中断编号即上图中的异常号。
EPSR包含了T位,该位用来表示当前是否处于Thumb状态。由于Cortex-M0处理器只支持Thumb状态,所以T位一般为1.清除该位(置零)后,执行置零会触发硬件异常中断。
PRIMASK,中断屏蔽特殊寄存器
PRIMASK仅有一位位宽,置位后,除了不可屏蔽中断(NMI)和硬件错误异常外的其他中断都会被屏蔽。
状态在异常进入/返回时自动保存/恢复
- 处理器发生异常时,硬件自动将下面的8个寄存器按以下顺序压栈:R0,R1,R2,R3,R12,LR,PC,XPSR(低地址-->高地址),存入当前主栈MSP;
-根据AAPCS, R0-R3,R12,LR,XPSR这些寄存器都是属于调用者保存寄存器;
- 栈帧需要双字对齐,如果异常产生时MSP指针未对齐,处理器会自动插入一个字;
处理器进入异常或中断时,LR的数值会被更新为EXC_RETURN数值,用于触发BX,POP等指令实现异常返回机制。
EXC_RETURN(32Bits)3个合法值:
0xFFFFFFF1 返回处理模式(嵌套异常发生的情况)
0xFFFFFFF9 返回线程模式并在返回中使用主栈(MSP)
0xFFFFFFFD 返回线程模式并在返回中使用进程栈(PSP)
异常处理流程
接受异常请求:
1) 中断和SysTick中断使能;
2) 未被NMI屏蔽掉;
3) 异常优先级大于当前执行的异常优先级。
压栈及相关寄存器更新:
1) 压栈并更新栈指针(8个registers被压栈:R0~R3, R12, R14/LR, R15/PC, xPSR);
2) 取出异常向量写入PC中;
3) 3个寄存器更新(LR<–EXC_RETURN, IPSR<–异常编号, NVIC<– 对应的中断控制和状态)
执行异常处理:
1) 自动定位异常向量,并处理;
2) 利用EXC_TURN的值来触发异常返回机制。
异常退出:
1) 寄存器出栈;
2) 恢复返回地址,并执行异常前程序。
异常优先级升级(Priority escalation)
四种情形下发生优先级提升:
1. 当前异常处理函数中触发了同种异常,且此异常为可配置优先级的异常。
2. 当前异常处理函数中触发了相同优先级或者更低优先级的异常。
3. 一个可配置优先级没有被使能,但是被触发了。
4. 当PRIMASK为1时,运行了SVC指令。
————————————————
When the current execution priority is less than HardFault, the processor escalates the exception priority to
HardFault in the following cases:
• When the group priority of a pending synchronous fault or supervisor call is lower than or equal to
the currently executing priority, inhibiting normal preemption. This applies to all synchronous
exceptions, both faults and SVCalls. This includes a DebugMonitorFault caused by executing a BKPT
instruction, but excludes all other DebugMonitorFaults.
• If a disabled configurable-priority fault occurs.
Escalating the exception priority to HardFault causes the processor to take a HardFault exception.
Examples of pending exceptions that cause priority escalation are:
• The exception handler for a configurable-priority fault causes the kind of exception it is servicing.
For example, if the processor tries to execute an undefined instruction in a UsageFault handler.
• The exception handler for a configurable-priority fault generates a different fault, and the handler for
that fault is the same or lower priority.
• A configurable-priority fault that is not enabled occurs.
• An SVC instruction occurs when PRIMASK is set to 1.
2. V6-M和V7-M的有什么区别?
V6架构处理器:ARM11
V6-M架构处理器:Cortex M0/M0+/M1
V7-M架构处理器:Cortex M3/M4
- 实际上,V6-M架构是基于V7-M的异常和调试特性以及现有V6架构的Thumb指令集,开发的一个新架构,着重于低功耗(M0/M0+)以及用于FPGA(M1);也就是说,从时间顺序上,V6-M后于V7-M。
- V6-M和V7-M很多方面都是相似的,例如中断处理,thumb-2技术以及架构特性,主要区别是V6-M的指令集更小,是V7-M指令集的子集,只支持多数16位指令和部分32位指令。
上图中,16位/32位thumb指令通过图标长度区分体现,例如DSB是32位指令,CMP是16位指令。
=======================================================
-- PPB总线主要用于NVIC, SCB, SysTick等处理器内部部件的访问,不能用于普通外设,因为PPB只支持私有访问,只允许32位访问,不存在写缓冲所有需要更多的时钟周期,也无法使用位段特性。