我正在为 Cortex M4F 编写线程代码。一切正常,我现在正在研究通过惰性堆栈使 FPU 上下文切换更有效。
我读过 ARM 的AN298,并实现了基于禁用 FPU 和处理UsageFault 的替代方法,但较低的 ( S0-S15) 寄存器没有被硬件正确保存/恢复。我认为问题出在图11:
据此,当PendSV运行时FPCAR应该指向任务A的堆栈中保留的空间。但正如我所见,由于CONTROL.FPCA在任务 C 中处于高位,FPCAR因此在进入 PendSV 时将更新为指向任务 C 的堆栈。如果是这样,S0-S15并且FPSCR将被保存到任务C的堆栈而不是任务A的堆栈中,这当然是不正确的。
我在这里遗漏了什么,还是应用程序注释错误?
附带说明一下,我检查了一些开源 RTOS。FreeRTOS 和 mbed RTOS 始终S16-S31在上下文切换期间进行堆栈,从而导致自动S0-S15堆栈,即它们仅使用惰性堆栈来减少中断延迟,但对任务进行完整的状态保存(如应用笔记中概述的第一种方法)。M4F 的 TNKernel 端口使用UsageFault 方法,但S0-S31通过软件完全保存/恢复,有效地绕过任何问题FPCAR(以 48 次加载/存储而不是 32 次为代价,16 个硬件加载/存储在恢复时被覆盖)。似乎没有人在只保留S16-S31.
(顺便说一句,这也发布在ARM Community 上,但那里似乎有很多问题没有答案。如果我在那里得到答案,我也会在这里复制它)