CM3 的堆棧分為兩個:主堆棧和進程堆棧。 那麼,這兩個棧分別在什麼情況下使用呢? 這時,我們看一下CM3的控制寄存器(CONTROL):控制寄存器用於定義特權級別,還用於選擇當前使用哪個堆棧指針。 CONTROL[1] 在 Cortex‐M3 的 handler 模式中, CONTROL[1]總是 ...
CM3 的堆棧分為兩個:主堆棧和進程堆棧。
那麼,這兩個棧分別在什麼情況下使用呢?
這時,我們看一下CM3的控制寄存器(CONTROL):控制寄存器用於定義特權級別,還用於選擇當前使用哪個堆棧指針。
CONTROL[1]
在 Cortex‐M3 的 handler 模式中, CONTROL[1]總是 0。線上程模式中則可以為 0 或 1。
僅當處於特權級的線程模式下,此位才可寫,其它場合下禁止寫此位。改變處理器的模
式也有其它的方式:在異常返回時,通過修改 LR 的位 2,也能實現模式切換。
而在uC/OS-II中利用的就是LR的位2來進行堆棧模式的切換,其實我們在上一篇文中也有說到,就是PendSV_Handler_Nosave中的這條指令ORR LR, LR, #0x04 將位2賦1,這樣退出異常時切換回 PSP ,之後就可以完成任務的切換。
響應異常的第一個動作,就是自動保存現場的必要部分:依次把xPSR, PC, LR, R12以及R3‐R0由硬體自動壓入適當的堆棧中:如果當響應異常時,當前的代碼正在使用PSP,則壓入PSP,即使用線程堆棧;否則壓入MSP,使用主堆棧。
大家要記住,一旦進入了中斷服務程式,CPU就將一直使用主堆棧(MSP)。
uC/OS-II的任務,也可以叫做它的線程,使用的堆棧就是PSP,低優先順序任務到高優先順序任務的切換也正是由PSP完成的。
當開發的程式比較簡單(CM3不跑系統的時候)時,可以從頭到尾都只使用 MSP。這時,只需要保證開出一個容量夠大的堆棧,再把 MSP 初始化到其頂即可——這也是單片機開發最常見的做法。
可能我理解不周,請謹慎參考,我會後期完善,謝謝支持!