前言
??ARM篇主要介紹一下寄存器和中斷機制,至于匯編這一塊…還請大家感興趣自行學習
1.寄存器
- R0 - R3 R4 - R11 寄存器
R0 - R3一般用作函數傳參
R4 - R11用來保存程序運算的中間結果或函數的局部變量
在函數調用過程中
- 注意在發生異常的時候 cortex-M0架構會自動將R0-R3壓入棧中, 這也是為什么我們的PendSV只用壓入R4 - R11
-
R12 沒啥用
-
R13寄存器
R13寄存器又叫做堆棧指針寄存器SP 總是指向當前正在運行的函數的棧幀-
MSP 和 PSP
對于 cortex-M3架構 存在兩個SP 指針 一個 MSP 一個 PSP
- PSP只能被用作線程模式 MSP可以在 線程/handler模式運行
具體的等后面模式做詳解
- PSP只能被用作線程模式 MSP可以在 線程/handler模式運行
-
FP 與 SP
??前面將函數調用過程的時候講到了 棧幀是靠這倆寄存器FP和SP維護的 可是為啥沒見FP寄存器呢? FP似乎通常是R11寄存器 但不絕對
-
-
R14寄存器—LR寄存器
- 用來保存保存上一級函數調用者的返回地址,這樣當我們函數調用返回的時候就知道從哪里接著運行了
- 當異常發生時,LR中保存的值等于異常發生時PC的值減4(或者減2),因此在各種異常模式下可以根據LR的值返回到異常發生前的相應位置繼續執行
- 當中斷發生的時候,LR寄存器的值會被設定為"EXC_RETURN"
- BL function
當我們通過這樣的指令跳轉的時候 就會更新我們的LR寄存器的值了 - BX LR
這個我們在RTOS的PendSV函數的最后會看到 BX LR 指令 這是因為PendSV結束調用時還處于特權模式(LR = EXC_RETURN),而我們實際上是想返回線程模式的 所以用BX LR 而不是 MOV PC, LR
-
R15寄存器—PC寄存器
每取一次指令,PC的值會自動 + 8 -
各種狀態寄存器
不必關心 -
ARM的三級流水線
??一條指令的執行分為三步:取址, 譯碼 和 執行 每一條都需要一個時鐘周期 所以一條指令需要三個時鐘周期。 那如果我們只有第一條指令執行完才執行第二條 就意味著取址單元會有兩個時鐘周期啥也不干。
所以引入流水線就好了
- 為什么是PC = PC + 8 呢
這么理解
“正在取值的指令” = “正在執行的指令” + 8 *
就對了,反正這也是給你看的不是給機器看的…
可以看到對于第一條指令add r0,r1,#5真正執行的時候,我們取的是第三條指令cmp r2,#3的值
- 為什么是PC = PC + 8 呢
-
順序執行與亂序執行
因為我們的指令很有可能下個指令依賴上個指令的結果,那此時三級流水線就出問題了
比如上個指令的結果還沒放回內存了 這邊已經從內存開始取數據了
此時就得加入空指令 暫停流水線了–效率低下
所以就會有亂序執行–有專門邏輯電路進行分析做這個事
2.特權與模式
- cortex-M3的模式
兩種模式 – handler模式與線程模式
兩種特權 – 用戶級和特權級 - ARM的七種模式
- 用戶模式(User):這是唯一的非特權模式,
- 快速中斷模式(FIQ, Fast Interrupt Request):
- 標準中斷模式(IRQ, Interrupt Request)
- 管理模式(SVC, Supervisor)。
- 中止模式(Abort)
- 未定義模式(Undefined)
- 系統模式(System)
??用戶級和特權級是針對訪問權限:特權級訪問寄存器不受限,用戶級不行
??模式是針對運行狀態: 觸發異常了就得進入 handler模式 普通狀態就是線程模式
??所以不能在用戶級去操作handler模式,但是線程模式下特權級還是用戶級都無所謂啦
- 復位后的狀態
復位后,處理器默認進入線程模式(MSP),特權極訪問
可以通過修改CTRL寄存器回到線程模式(PSP指針)
但是線程模式可就不能修改CTRL寄存器了—那想回去怎么辦?觸發異常再異常中修該
3.存儲區映射
對于32位的處理器 地址空間是4個G 這4G對于ARM來說是這么定義的
異常
??對于所有的異常都進行了編號 前15種是系統異常 后面的都是外部中斷
??我們可以看到對于后面幾個異常是可編程的,這個在RTOS的任務切換很重要,我們一般會把PendSV這個異常設定為最低優先級(0xffffffff)—為了在對所有中斷都響應后在切換任務
-
搶占優先級和響應優先級
高搶占優先級可以打斷低搶占優先級
但是同搶占優先級下,高響應優先級打斷不了低的響應優先級 -
中斷向量表—處理中斷的關鍵
這個是在starup.s中定義的 一般我們也不會有重新定義新的中斷的需求
-
對中斷的響應
正常來說需要我們在中斷服務程序清除對應的標志位
如果不清除會咋樣—那就反復進入該中斷處理程序操作
如果極短時間多次請求–一般只會響應一次,因為中斷就懸起了一次
假如在中斷服務函數執行過程中,又觸發了一次相同的中斷–就會再執行一次
-
NVIC中斷控制器
- 中斷的懸起與解懸
- 中斷的優先級控制
- 對中斷響應的暫時屏蔽
中斷
- msp與psp指針
MSP:復位后缺省使用的堆棧指針,用于操作系統內核以及異常處理例程(包括中斷服務例程)
PSP:由用戶的應用程序代碼使用。
兩個堆棧指針,同一時刻只能用一個。
作用:提升程序健壯性。一定程度上保證應用的數據(棧)空間不會溢出到操作系統數據(棧)空間 - 中斷發生后做了什么
當一個中斷發生的時候 我們的內核到底做了什么-
寄存器入棧–保存現場
-
地址總線從向量表查詢中斷向量
-
更新寄存器–此時就進入handler模式了同時使用的也是MSP指針了
-
跳轉執行中斷服務程序
-
中斷返回–包括把之前保存的寄存器的值自動彈出來(恢復現場)
-
- 中斷的遞歸調用
不用我等操心 但是需要我們注意的是就是給棧提供一個合適的大小 - 中斷與異常的區別
中斷——外部事件引起,正在運行的程序所不期望的–異步的
異常——內部執行指令引起–同步的