大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是Cortex-M中斷向量表對齊原則。
今天這篇文章的内容主要來自于五年前做 Kinetis K32W 系列雙核啟動時的發現,最近正好有同僚碰到了 ARM Cortex-M 中斷向量表對齊問題,于是痞子衡想起了這事(感慨自己記性還挺好),翻出了五年前的郵件,将當時測試結果重新整理成文。
前段時間痞子衡剛寫了篇 《Cortex-M中斷向量表原理及其重定向方法》,簡單介紹了中斷向量表工作機制,今天咱們接着來聊聊這個中斷向量表對齊的事:
中斷向量表就是一個集中儲存系統全部中斷處理函數(xxxIRQHandler)位址的常量數組(函數位址要占 4 個位元組,是以數組中每個元素大小為 4 位元組),表中元素編号如下:

Cortex-M 核心(除了CM0)子產品 SCB 裡有個專門的 VTOR 寄存器用來控制中斷向量表首位址,程式運作起來後使用者可以配置 SCB->VTOR 寄存器來重設中斷向量表位址。
SCB->VTOR 寄存器低 7bit 是保留的(永遠0),是以中斷向量表首位址一定要是 128 位元組(0x80)對齊的,這個毫無疑問!但是僅僅 128 位元組對齊就行了嗎?這個是要看情況的,如下 Cortex-M Generic User Guide 手冊裡關于 VTOR 寄存器描述裡有這樣一段話(紅框内),這段話的意思是向量表首位址需要按 0x80 向上對齊(還得是 2 的整數幂)以覆寫項目中實際用到的數值最大中斷号(xxx_IRQn)。
Note: 比如項目中實際用到最大外設中斷為 IRQ20,則最小向量表大小為(16 + 21)* 4 位元組,那麼向量表首位址需要至少以 0x100 對齊。
如果中斷向量表首位址沒有按規定對齊,會發生什麼後果呢?我們找一塊闆卡來實測下,選擇的晶片是恩智浦 i.MXRT1011,這是顆 Cortex-M7 核心的 MCU,除了 16 個系統中斷外,還包含 80 個外設中斷,中斷向量表裡一共 96 個有效中斷,見如下 startup_MIMXRT1011.s 檔案中具體中斷響應函數定義:
因為 i.MXRT1011 裡一共 96 個中斷,按規定,中斷向量表首位址至少要按 0x200 對齊。我們現在故意不按規定來設對齊,先選擇一個測試工程 \SDK_2.10.0_EVK-MIMXRT1010\boards\evkmimxrt1010\demo_apps\hello_world\iar(flexspi_nor_build),修改 hello_world.c 檔案,加一個 relocate_vector_table() 函數,将中斷向量表重定向到 NEW_VECTOR_ADDRESS:
萬事俱備,我們現在需要使能一些中斷來驗證,痞子衡分别選取了 SysTick、LPUART1、GPT2、WDOG2、TEMP_LOW_HIGH、WDOG1 六個中斷,它們的使能代碼都可以從 SDK\boards\evkmimxrt1010\driver_examples\ 裡找到,這裡不予贅述。
将 NEW_VECTOR_ADDRESS 設為 ITCM 偏移 0x80 處,則中斷向量表被重定向到了按 0x80 對齊的地方,分别測試標明的 6 個中斷,最終結果如下:SysTick、TEMP_LOW_HIGH、WDOG1 中斷響應是正常的,而 LPUART1、GPT2、WDOG2 實際響應的中斷函數卻是 MemManage、SysTick、DMA13 位置,這裡出現了異常。
将 NEW_VECTOR_ADDRESS 設為 ITCM 偏移 0x100 處,則中斷向量表被重定向到了按 0x100 對齊的地方,分别測試標明的 6 個中斷,最終結果如下:SysTick、LPUART1、GPT2、WDOG2 中斷響應是正常的,而 TEMP_LOW_HIGH、WDOG1 實際響應的中斷函數卻是 SysTick、DMA10 位置,還是出現了異常。
将 NEW_VECTOR_ADDRESS 設為 ITCM 偏移 0x180 處,則中斷向量表被重定向到了按 0x180 對齊的地方,實測效果跟 2.1 節一緻。
将 NEW_VECTOR_ADDRESS 設為 ITCM 偏移 0x200 處,則中斷向量表被重定向到了按 0x200 對齊的地方,6 個中斷都能正常響應,畢竟是符合 ARM 手冊裡對齊規定。
因為 i.MXRT1011 最多僅 96 個有效中斷,有些對齊測試不能完全覆寫,痞子衡後來又在 i.MXRT1176 上(最多 234 個有效中斷)以同樣方式測了一遍,最終總結到現象如下:
關于第 2 節裡中斷向量表不對齊的測試結果發現有什麼意義呢?其實是有的,我們可以利用這個結果來精簡中斷向量表的大小,這對于一些 Flash 容量較小的 MCU 上開發應用程式時優化代碼尺寸會有幫助,底下痞子衡會專門寫文章具體介紹。
至此,Cortex-M中斷向量表對齊原則痞子衡便介紹完畢了,掌聲在哪裡~~~
文章會同時釋出到我的 部落格園首頁、CSDN首頁、知乎首頁、微信公衆号 平台上。
微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。
最後歡迎關注痞子衡個人微信公衆号【痞子衡嵌入式】,一個專注嵌入式技術的公衆号,跟着痞子衡一起玩轉嵌入式。
衡傑(痞子衡),目前就職于恩智浦MCU系統部門,擔任嵌入式系統應用工程師。
專欄内所有文章的轉載請注明出處:http://www.cnblogs.com/henjay724/
與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]
可以關注痞子衡的Github首頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。
關于專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回複免費(劃重點)答疑。
痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。