ARM中斷處理分析
中斷的基本含義應該是允許CPU在執行某個(gè)代碼序列的過(guò)程中停下來(lái)執行另外一個(gè)代碼序列,這里有兩層意思,一個(gè)是要切換到另一個(gè)場(chǎng)景,另一個(gè)是當執行完畢之后必須能夠恢復原來(lái)的場(chǎng)景。
本文引用地址:http://dyxdggzs.com/article/201611/316860.htm首先討論如何才能切換到一個(gè)新的場(chǎng)景,
當一條指令的執行完之后,CPU會(huì )檢查有沒(méi)有中斷產(chǎn)生,如果有就halt當前流水線(xiàn)。重載PC寄存器后重新啟動(dòng)流水線(xiàn)。
ARM7一般為3級流水線(xiàn)價(jià)格,分別是取指、譯碼和執行。PC寄存器中存放的是當前時(shí)刻(CPU機器時(shí)鐘周期)取指操作的目標地址,即CPU即將執行的指令的地址由PC寄存器指定,正常情況下PC指針的內容是CPU自動(dòng)調整的——每個(gè)時(shí)鐘周期自動(dòng)+4,在發(fā)生跳轉時(shí),可以通過(guò)直接執行修改PC值的指令來(lái)實(shí)現。中斷的本質(zhì)就是一次跳轉,跟函數調用其實(shí)沒(méi)有什么分別(只不過(guò)增加了一些硬件支持),所以這里第一步是將PC值寫(xiě)成對應的中斷入口地址,比如IRQ就是0x18.
接下來(lái)還需要切換ARM的內核模式到相應的中斷模式。寫(xiě)完P(guān)C值以后,下一個(gè)時(shí)鐘周期流水線(xiàn)就開(kāi)始從0x18處取指,然后譯碼、執行。中斷入口地址處存放的是中斷向量表,所謂中斷向量就是另一個(gè)跳轉指令,比如LDR PC, [PC,#24] ,執行完這個(gè)跳轉之后理論上CPU就已經(jīng)從一個(gè)新的地址開(kāi)始執行了。這個(gè)過(guò)程的實(shí)現是軟硬件結合的結果,硬件負責第一次加載PC,而軟件負責再次修改PC值,將程序指向指定的代碼序列。
還必須考慮如何恢復原執行場(chǎng)景,這里跟剛才一樣,一部分工作由硬件實(shí)現,另一部分必須由軟件負責實(shí)現。因為第一次修改PC到中斷入口地址是硬件完成的,所以第一次保存中斷現場(chǎng)的工作也只能由硬件完成,這個(gè)工作包括將PC被修改前的值保存到LR_irq寄存器中,并將當前PSR寄存器的值保存到SPSR_irq中。為了實(shí)現中斷嵌套,可能硬件還需要將當前中斷信息壓棧(硬件棧,而不是內存)以便當嵌套發(fā)生時(shí)用于恢復。
當程序執行到ISR后,硬件的工作基本完成,軟件代碼將在當前CPU模式下運行,這可能會(huì )修改LR和PSR等寄存器,所以在執行中斷處理代碼之前需要對這兩個(gè)寄存器進(jìn)行保護,否則一旦被破壞以后就無(wú)法恢復。這里同樣需要保護的還包括工作寄存器等。
軟件的職責還包括清掉設備中斷標志。
最后,當ISR結束時(shí),軟件負責將CPU恢復到中斷前的狀態(tài),然后利用已保存的LR地址跳轉到中斷時(shí)執行代碼的下一行代碼開(kāi)始繼續執行。
當涉及到中斷嵌套的情況時(shí),重復上述過(guò)程,只是硬件此時(shí)不需要在改變CPU的工作模式。
當涉及到有操作系統的時(shí)候,這個(gè)過(guò)程會(huì )變得稍微復雜一些。
首先在進(jìn)入中斷之前OS需要記錄當前中斷嵌套的層數,并且在中斷退出之后恢復到被中斷上下文之前做一次判斷,因為中斷程序可能改變當前就緒態(tài)優(yōu)先級最高的任務(wù),如果此時(shí)優(yōu)先級最高的任務(wù)不再是先前被中斷的任務(wù)時(shí),得到恢復并繼續執行的將是該當前優(yōu)先級最高的就緒態(tài)的任務(wù)。
這里只有在中斷嵌套層數為0時(shí)OS才會(huì )提供這樣一次機會(huì ),否則將恢復到被中斷的ISR中繼續執行中斷處理程序。
評論