我正在爲Cortex M4F編寫線程代碼。一切正常,我正在研究通過延遲堆棧使FPU上下文切換更高效。Cortex-M4F惰性FPU堆棧
我讀過ARM的AN298,我實現了基於禁用FPU和處理UsageFault的替代方法,但較低的(S0-S15
)寄存器沒有被硬件正確保存/恢復。我認爲問題在於圖11:
根據這一點,當PendSV的運行FPCAR
應該指向任務A的堆棧保留的空間。但就我所見,由於CONTROL.FPCA
在任務C中很高,因此在進入PendSV時,FPCAR
將更新爲指向任務C的堆棧。如果是這樣,S0-S15
和FPSCR
將被保存到任務C的堆棧而不是任務A,這當然是不正確的。
我在這裏錯過了什麼,或者是appnote錯誤?
一個側面說明,我檢查了一些開源RTOS。 FreeRTOS和mbed RTOS總是在上下文切換期間堆疊S16-S31
,導致自動堆棧,即它們僅使用延遲堆棧來減少中斷延遲,但是對任務進行全狀態保存(如在appnote中概述的第一種方法)。用於M4F的TNKernel端口使用UsageFault方法,但通過軟件完全保存/恢復S0-S31
,有效地繞過FPCAR
(以48個加載/存儲而不是32個,16個硬件在恢復時被覆蓋爲代價)的任何問題。似乎沒有人使用UsageFault方法,只保留S16-S31
。
(順便說一句,這也張貼在ARM Community,但很多問題似乎置之不理那裏。如果我得到一個答案,我會在這裏複製它,太)
從應用程序注意:「FPCAR寄存器指向當前堆棧中的一部分堆棧空間......」因此它應該指向被搶佔任務的堆棧。 –
@Drueger正確。但是圖紙意味着當任務C被PendSV搶佔時,它仍指向任務A的框架。這就是爲什麼我很困惑,我不知道我是否誤解了它,或者如果appnote中的某些內容是錯誤的。 –
我認爲這表明當FPU被禁用時FPCAR不會被更新。這就是爲什麼它繼續指向任務A的堆棧,直到啓用了FPU的任務C被搶佔爲止。然後保存FPU上下文,直到另一個任務實際需要FPU。 –