1. 程式人生 > >淺析arm的異常、中斷和arm工作模式的聯絡

淺析arm的異常、中斷和arm工作模式的聯絡

說到異常向量,會讓人聯想到中斷向量。其實,中斷是屬於異常的子集的,也就是說中斷其實是異常其中的一種。

   回到異常向量,他其實是一張表格,每個格子裡存放的是一個地址,或者是一個跳轉命令,不管是哪個,其目的都是讓PC跳轉到真正處理異常的程式碼的地方。

以下是arm的異常向量表:

wpsEE9.tmp

圖1

初步介紹完異常向量,就來對比下ARM的arm的7種工作模式:

wpsEFA.tmp

圖2

User : 非特權模式,大部分任務執行在這種模式

FIQ :   當一個高優先順序(fast) 中斷產生時將會進入這種模式

IRQ :   當一個低優先順序(normal) 中斷產生時將會進入這種模式

Supervisor :當復位或軟中斷指令執行時將會進入這種模式

Abort : 當存取異常時將會進入這種模式

Undef : 當執行未定義指令時會進入這種模式

System : 使用和User模式相同暫存器集的特權模式

可以發現arm的7種工作模式其實是和arm的異常向量表有著一定的對應關係的。

接著來看ARM的一個非常重要的暫存器——CPSR程式狀態暫存器,如圖二所示:該暫存器在arm的任何工作模式中都存在,且是被所以工作模式共用的。

暫存器每一位的含義如下圖所示:

wpsF1A.tmp

圖3

以上3者有著莫大的關聯,結合三者分析,就會明白很多東西。

其一、arm的7種工作模式,和異常向量表有著一定的對應關係。 如SVC模式下發生普通中斷(IRQ)arm自動切換到IRQ模式,進入IRQ模式後PC就會指向IRQ對應異常向量表,及0x18這個位置。

再比如復位時,就會進入svc模式,並且跳到Reset對應的異常向量表,及0x00位置(這也是為什麼程式是從0x00開始執行的)

其二、工作模式的切換有主動和被動之分。上面所說的就是被動切換,他是隨著某種異常的發生而導致的切換。

主動切換,就要靠cpsr這個暫存器了。可以看到這個暫存器的末四位就是用來設定進入哪種模式的。

何時需要cpsr主動切換模式呢:

1、一開始就想進入某種模式。如:一開始設定所有模式下的sp地址。示例如下:

wpsF1B.tmp

2、進入某種模式後,想切換到之前的模式。這個過程通常是通過讀回SPSR的值。示例如下:

wpsF2B.tmp

接著,我們來區分異常和中斷的區別和聯絡:

1、中斷可以看作是異常的一種情況。

2、中斷是可以遮蔽的,如通過cpsr暫存器的I位和F位分別遮蔽IRQ和FIQ。而異常是無法遮蔽的。

3、異常/中斷髮生時,PC都會指向相應的向量表。異常的發生往往會導致模式的自動切換。

4、IRQ和其他模式稍有不同。因為被動切換到IRQ模式下的情況有很多種,換句話就是,很多種中斷,都會導致進入IRQ模式。進入IRQ模式還需要判斷是那種情況導致了中斷,所以IRQ往往還對應一張中斷向量表。(區分於異常向量表)相當於異常向量表的子級表。

最後看,在模式切換時,都發生了什麼?

1、當模式發生切換時(主動或者被動),硬體會自動幫我們完成一些事情。然後還需要軟體完成一些事情。

做好這兩件事,就可以在模式之間切換而不會相互影響,當然對應程式設計師而言只需要做好後者。

2、硬體幫我們完成的事情,是在模式切換時隨之完成,而軟體要完成的任務,是在模式切換之後。這點需要十分注意!比如當前是SVC模式切換到IRQ模式。那麼軟體需要完成的事情,是在當前IRQ模式下完成的。

3、那麼硬體完成了什麼事情,軟體又需要做什麼呢?

3.1、硬體完成的事情有:

wpsF2C.tmp

切換到新的模式後,用的就是當前模式下的sp以及lr,但是pc只有一個。由於硬體幫我們

完成的一些事。所以當前IRQ模式下的lr暫存器存放的其實是上個模式SVC的PC值。當前IRQ模式下的

SPSR暫存器存放的其實是上個模式SVC的CPSR值。這充分為返回上一個模式做好了準備。

3.2、所以軟體需要完成的任務有:

3.2.1、儲存當前共用暫存器的值,(如SVC模式和IRQ模式共用r0~r12 以及r15及pc)到當前模式的棧記憶體。保證之前模式的值不被破壞。

這裡CPSR雖然也是共用的,但是不用儲存到棧中,這是因為硬體會自動把上個模式的CPSR儲存到當前模式的SPSR。

而SPSR直到中斷返回,及切換到之前的模式才會用到。有點同學會問了,pc的值也會由硬體自動儲存到lr,為什麼還需要儲存到棧中呢?這是因為lr和SPSR不同,在中斷執行的過程中,很可能需要使用lr,為了不把之前的pc值沖掉還是先將其發到棧中儲存。

3.2.2、進入中斷處理函式。處理中斷。

3.2.3、中斷返回,將之前儲存到棧裡的值讀回,並SPSR的值賦值給CPSR實現主動切換到之前的模式。示例程式碼:

wpsF2D.tmp

最後,聊一個面試經常問的問題,FIQ相比IRQ,FIQ稱為快速中斷,IRQ稱為普通中斷。FIQ為什麼比IRQ快!

我們可以結合圖1和圖2進行分析:

1、先看圖1,FIQ的異常向量地址為0x1C,位置處於最頂部,這就意味著,FIQ真正的異常處理程式碼可以緊接著0x1C,及無需跳轉,不跳轉意味著無需打斷arm的流水線,所以可以提高中斷響應。

2、再看圖2,FIQ模式下具有更多的獨立暫存器,如r8~r14,這些暫存器都是FIQ模式下獨自享用的。這就意味著,當發生快速中斷,進行模式切換時,只有少量的暫存器需要備份到棧中,從而也能節省時間,提高中斷的響應速度。

以上兩點就是FIQ為什麼比IRQ快的原因,別小看節省的這麼一點點時間,有的時候就是這麼“兵貴神速”。

作者:宋桓公 
出處:http://www.cnblogs.com/douzi2/ 
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!歡迎各位轉載,但是未經作者本人同意,轉載文章之後必須在文章頁面明顯位置給出作者和原文連線,否則保留追究法律責任的權利。