一、 概述
复位异常是一种特殊的异常,这里简单介绍复位情况。(这里主要参考 armv7m)。
二、过程
对于复位,这里仅指 Armv7m 里面会出现的操作。
复位是一个特殊的异常,其进入过程与其他的异常有非常大的区别。例如进入、退出的时候都不会压栈、入栈等等。一旦断言,那么就会放弃当前的执行状态且不保存。
首先,复位会将当前模式改为 Thread 模式,这个与其他异常进入是要变为 Handler 模式不一样。
然后,开始将大量的寄存器进行初始化,如下:
(1)优先级提升寄存器初始化
① PRIMASK[0]=0;
② BASEPRI[7:0]=0x00;
(2)特殊寄存器初始化
① CONTROL=0;
CONTROL 定义如下:
位数 | 说明 | 定义 |
Bit0 nPRIV | Thread 模式的执行权限 | 0:特权模式 |
1:非特权模式 | ||
Bit1 SPSEL | 定义栈顶指针寄存器使用哪个 | 0:使用 SP_main |
1;在 Thread 模式使用 SP_Process,Handler 模式不使用该值 | ||
Bit2 FPCA | 这个需要带 FP 扩展,定义 FP 扩展是否使能 | 0:FP 扩展不激活 |
1:FP 扩展激活 |
软件必须使用ISB屏障指令来确保对控制寄存器的写入在执行下一条指令之前生效。
如果当前的内核实现了 FP 扩展,还需要对下列寄存器实现初始化②~⑦:
② CPACR.CP10 和 CPACR.CP11 赋值为0
CPACR 是指定协处理器访问权限,如下:
位数 | 31~24 | 23~22 | 21~20 | 19~16 | 15~14 | 13~12 | 11~10 | 9~8 | 7~6 | 5~4 | 3~2 | 1~0 |
定义 | Reserved | CP11 | CP10 | Reserved | CP7 | CP6 | CP5 | CP4 | CP3 | CP2 | CP1 | CP0 |
这里面 CP8~CP15 都是被 ARM 使用,但 CP10 和 CP11 是用于 浮点协处理器的,我们可以进行配置。
值定义如下:
值 | 说明 |
0b00 | 拒绝访问。任何尝试访问都会产生NOCP UsageFault |
0b01 | 仅限特权访问。无权限访问产生NOCP UsageFault |
0b10 | Reserved |
0b11 | Full 访问 |
③ FPDSCR 除了 Reserved 之外全设置为0
FPDSCR 是 保存处理器在创建新的浮点上下文时分配给FPSCR的浮点状态控制数据的默认值,只有特权权限才能访问
位数 | 31~27 | 26 | 25 | 24 | 23~22 | 21~0 |
定义 | Reserved | AHP | DN | FZ | RMode | Reserved |
④ FPCCR 的 ASPEN 和 LSPEN 重置为 1, LSPACT 置为0
FPCCR 是 FPU 上下文的控制寄存器,只有特权权限才可访问
⑤ FPCAR 设置为 UNKOWN
FPCAR保存在异常堆栈帧上分配的未填充的浮点寄存器空间的位置。FPCAR指向为S0保留的堆栈位置。只有特权权限才能访问
位数 | 31~3 | 2~0 |
定义 | ADDRESS | Reserved |
⑥ 这里写的是 FPFSR 设置为 UNKOWN,但目前找不到该寄存器的定义,或许指的是 FPSCR?
⑦ 将浮点数据寄存器 S[] 寄存器全赋值为 0
(3)将所有激活的异常状态重置为0
(4)将 SCS 中具有体系结构定义的重置值的所有寄存器恢复为这些值
(5)清除处理器的全局独占监视记录
(6)清除处理器事件寄存器
(7)将通用寄存器设置为 UNKOWN:’00’,向量表基地址设置为 0
(8)将主栈顶指针寄存器赋值为向量表指定值,LR 设置为 0xFFFFFFFF
(9)将 APSR 设置为 UNKOWN, IPSR 和 EPSR 除了 EPSR.T 设置为 复位异常入口地址bit0 值之外,其他全置为0。然后 PC 值指向复位异常入口地址。
三、复位管理
除了上下电复位之外,还有 Local 复位。Local 复位进复位一部分 debug 逻辑
AIRCR 提供了两种系统复位:
- SYSRESETREQ 请求外部系统资源复位,这将造成 Locak 复位,这个是不保证立即同步复位
- VECTRESET 造成 Local 复位,这是一个调试特性
AIRCR 还提供了一种机制复位所有异常活动状态,即将 VECTCLRACTIVE 置1,但这个不影响任何异常的挂起状态
四、参考文档
ARM:《DDI0403E_d_armv7m_arm.pdf》