【简介】
Cortex‑M4/M7 内核集成硬件 FPU 浮点单元,拥有独立的 S0~S31 浮点通用寄存器与 FPSCR 浮点状态寄存器。在触发中断或异常时,若上文任务使用过浮点运算,内核硬件会自动将浮点寄存器与 R0~R3、R12、LR、PC、xPSR 等通用寄存器一同压栈保护现场。由于浮点寄存器数量较多,完整压栈数据量显著增大,硬件完成入栈操作所需时钟周期增加,直接导致异常响应时间变长。为缓解该问题,内核支持 Lazy FPU 懒压栈机制,进入异常时先仅压入通用寄存器以保证快速响应,仅当中断服务程序自身使用 FPU 时才补压浮点寄存器,从而最大限度减少浮点上下文切换对系统实时性的影响。以下是 Cortex-M 架构中对此特性的描述。


FPU 寄存器的延迟入栈需要在进入中断的“上文”环境下触发FPU寄存器的访问,我们如何触发FPU 的访问后然后触发中断的操作呢,我们可以使用此贴(【S32K3XX】MCM FPU 异常状态检测)的方法触发FPU的除0访问从而触发中断。在进入异常现场钱如何确认当前“上文”环境有FPU访问操作呢?可以从异常的返回值EXC_RETURN 的bit 4 来获取这个信息。

本地触发FPU的访问后进入MCM的中断时读取的EXEC_RETURN[4] = 0 代表进入异常前有FPU的寄存器访问环境。

FP 寄存器延迟入栈的操作,在异常中如果有浮点的寄存器操作时会触发FPU的寄存器的入栈处理,否则为了节约时间就不进行入栈处理,FPU的栈帧地址在cortex-m 架构中有专门的寄存器FPCAR 寄存器来报错FPU 的寄存器栈帧地址信息。


上述截图可以看出FPCAR 寄存器的地址位PSP 进行R0~R3,R12,LR,PC,XPSR 栈帧保存后的地址,下图能更清晰的看出上述的memory layout布局。

因为本地的测试代码并没有在异常中触发FPU的访问实际并没有将FPU的寄存器数据压入到栈帧中,被你的修改代码触发FPU寄存器的访问,来继续查看FPU是否入栈了。
修改中断处理函数添加FPU 状态寄存器的访问触发延迟压栈的特性。

在次debug 发现已经触发FPU 的s0~s15 和 FPSCR 寄存器已经触发延迟压栈的特性了。

FPU 的延迟压栈的特性也可以通过寄存器来关闭此特性。

我要赚赏金
