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