記得在DSP TMS32F2812中,中斷向量的初始化是由一段地址拷貝代碼完成的,在STM32(Cortex-M3)中沒有顯示的代碼拷貝,只有啟動代碼進行了向量的初始化,一直以為是編譯器在程序影像中自己完成了相關向量的拷貝,即,拷貝到固定的NVIC區,事實上並不是這樣,cortex-m3並沒有一塊專門用於存放NVIC向量表的地方,這張表實際是存放在代碼(程序映像)的開始,下面引用cortex-M3權威指南進行解釋:
當發生了異常並且要響應它時,CM3需要定位其服務例程的入口地址。這些入口地址存儲在所謂的“(異常)向量表”中。缺省情況下,CM3認為該表位於零地址處,且各向量占用4字節。因此每個表項占用4字節,如表7.6所示。
因為地址0處應該存儲引導代碼,所以它通常映射到Flash或者是ROM器件,並且它們的值不得在運行時改變。然而,為了支持動態重分發中斷,CM3允許向量表重定位——從其它地址處開始定位各異常向量。這些地址對應的區域可以是代碼區,但更多是在RAM區。在RAM區就可以修改向量的入口地址了。為了實現這個功能,NVIC中有一個寄存器,稱為“向量表偏移量寄存器”(在地址0xE000_ED08處),通過修改它的值就能重定位向量表。但必須注意的是:向量表的起始地址是有要求的:必須先求出系統中共有多少個向量,再把這個數字向上“圓整”到2的整次冪,而起始地址必須對齊到后者的邊界上。例如,如果一共有32個中斷,則共有32+16(系統異常)=48個向量,向上圓整到2的整次冪后值為64,因此向量表重定位的地址必須能被64*4=256整除,從而合法的起始地址可以是:0x0, 0x100, 0x200等。向量表偏移量寄存器的定義如表7.7所示。
如果需要動態地更改向量表,則對於任何器件來說,向量表的起始處都必須包含以下向量:
主堆棧指針(MSP)的初始值
復位向量
NMI
硬fault服務例程
后兩者也是必需的,因為有可能在引導過程中發生這兩種異常。
可以在SRAM中開出一塊空間用於存儲向量表。在引導期間先填寫好各向量,然后在引導完成后,就可以啟用內存中的新向量表,從而實現向量可動態調整的能力。