无码专区一区人妻|人妻系列一区二区播放|国产免费牲交大片高清|日韩黄色无码一区二区三区|久久精品国产亚洲二区三区|欧美综合在线一区二区三区|精品无码国产自产拍在线观看蜜|999zyz精品视频在线播放

您當(dāng)前的位置 :寧夏資訊網(wǎng) > 科技 >  內(nèi)容正文
投稿

STM32在線升級中斷向量重定向深度剖析!

寧夏資訊網(wǎng) 2020-11-19 06:55:56 來源: 閱讀:-

在做stm32 iap升級固件的時候通常需要多份中斷向量表。比如bootloader的中斷向量表在0x00000000位置,應(yīng)用程序的中斷向量表則會放在flash的另一個地方或者是放在RAM中運行。

要維護(hù)向量表位置就需要用VTOR這個東西,那么就要先從VTOR來聊聊, 先弄清這個東西又是干嘛的。

VTOR是arm內(nèi)核的一個寄存器,叫做中斷向量偏移量寄存器。當(dāng)系統(tǒng)上電啟動的時候CPU會從先找到中斷向量表的位置,然后從表中找到復(fù)位中斷Reset_Handler,而main函數(shù)的執(zhí)行實際上就是在復(fù)位中斷函數(shù)中的。如下匯編代碼就是復(fù)位中斷服務(wù)函數(shù),該函數(shù)在啟動文件中定義。在Reset_Handler 中會執(zhí)行__main(),而main函數(shù)又是被__main()調(diào)用了。

Reset_Handler    PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP

前面復(fù)習(xí)一下ARM處理器啟動到執(zhí)行main的一個大概流程。再回歸正題繼續(xù)探討這個VTOR。當(dāng)來一個中斷時,cpu就會從0x0000000+VTOR位置找到中斷向量表,然后再查表跳轉(zhuǎn)到對應(yīng)的中斷服務(wù)函數(shù)去執(zhí)行。所以你代碼里面存在多份中斷向量表是可以的,只需要動態(tài)改變VTOR的值就可以了。

STM32在線升級中斷向量重定向深度剖析

APP的中斷向量放在flash中:

如下圖所示,在運行bootloader的時候用的是他自己的bootloader,當(dāng)從bootloader跳轉(zhuǎn)到app以后就需要用app的向量表了。所以進(jìn)入APP的首要任務(wù)就是設(shè)置VTOR值為0x0x8001000,再產(chǎn)生中斷的時候讓cpu去app的向量表里找中斷服務(wù)函數(shù)入口。

STM32在線升級中斷向量重定向深度剖析

所以從在app中重定義向量表是不是很簡單。但是有個前提,就是要有VTOR寄存器。實際上,并不是所有stm32都帶有VTOR的。準(zhǔn)確的說是因為ARM-CORTEX-M0內(nèi)核的芯片沒有,所以stm32F0系列所采用M0內(nèi)核的芯片就沒有VTOR。但是還有需要注意的就是L0系列使用的M0+內(nèi)核和M0內(nèi)核又是不同的,是有VTOR的。

這就意味著stm32F0系列沒有辦法使用這種簡單的修改VTOR的方式重新定位APP的中斷向量表。那肯定還有其他思路,就是稍微麻煩一點。

中斷向量放在RAM中:

那就是把中斷向量表放在RAM中去,并且針對F0沒有VTOR的還必須把中斷向量表拷貝到RAM的起始地址。

為什么這樣做,因為前面我們提到過CPU默認(rèn)會認(rèn)為0x00000000處放的就是向量表。那么我們換種思路可以把RAM的地址映射到0x00000000處。這個通過配置SYSCFG寄存器的MEM_MODE就可以把RAM地址映射到0x00000000處。

STM32在線升級中斷向量重定向深度剖析

這時候再進(jìn)入到APP以后首要任務(wù)就是把APP的中斷向量表拷貝到RAM的起始地址,并且修改MEM_MODE位。

在代碼里面比較簡單的做法就是在ram起始地址處定義一個數(shù)組,上電以后把向量表拷貝到這個數(shù)組中。如下代碼是在MDK中定義的方法,在IAR或者GCC定義的方式會有區(qū)別。

__IO uint32_t vector_t[48] __attribute__((at(0x20000000)));

但是要編譯通過還需要在mdk配置里面把ram的起始地址設(shè)置為0x200000c0,前面的0xc0的空間騰出來存放定義的這個數(shù)組。

有VTOR的系列向量表放在RAM中

stm32F0系列內(nèi)核決定了即便把向量表放在RAM中也只能放在RAM的起始位置而不能任意放。但是有VTOR的型號就可以隨便放。這樣分配存放向量表的數(shù)組也可以不用定位在0x20000000位置了??梢匀缦路绞蕉x:

__align(256) uint32_t vector_t[48];

可以看到雖然沒有了必須放在ram起始地址的限制,但是還是要遵守一定的規(guī)則。就是對齊有要求的。比如L0系列有48個中斷向量,一共占用內(nèi)存為48*4=192bytes。擴(kuò)大為2的整次方為256:28=256。所以就要求向量存儲的地址必須是256對齊的。存放在0x0或者0x20000100都可以滿足要求。

另外這種方式雖然更靈活了一些,但是卻造成了一定RAM空間的浪費。我在這樣定義編譯以后查看MAP文件如下,紅色的區(qū)域空出來的一段內(nèi)存空間就會被浪費掉:

STM32在線升級中斷向量重定向深度剖析

關(guān)于0X00000000地址

前面說過默認(rèn)cpu會從0x00000000地址來取向量表,那么stm32的flash都是從0x8000000地址開始的,這時候不設(shè)置VTOR偏移為什么也可以正常運行。實際上當(dāng)從用戶flash啟動的時候,從0x8000000或者0x00000000訪問的都是同一片區(qū)域。所以cpu從0x0取向量表相當(dāng)于取的就是0x8000000地址處的數(shù)據(jù)。

更進(jìn)一步理解,stm32通過配置boot腳(或者SYSCFG中MEM_MODE位)有三種啟動模式選擇,這三種模式的本質(zhì)就是看把那個區(qū)域重映射為0x00000000地址。這樣CPU取第一條指令就是從哪里?。?/p>

  1. 從用戶flash區(qū)啟動,用戶flash起始地址被映射到0x00000000上
  2. 從系統(tǒng)flash區(qū)啟動,系統(tǒng)flash起始地址被映射到0x00000000上,上電就執(zhí)行內(nèi)置的bootloader
  3. 從RAM區(qū)啟動,RAM起始地址被映射到0x00000000上,這時候你再回過去看我剛才說的F0無VTOR寄存器實現(xiàn)IAP就是這樣的思路。向量表放在了RAM區(qū)域的起始地址。

(正文已結(jié)束)

推薦閱讀:每日江蘇

免責(zé)聲明及提醒:此文內(nèi)容為本網(wǎng)所轉(zhuǎn)載企業(yè)宣傳資訊,該相關(guān)信息僅為宣傳及傳遞更多信息之目的,不代表本網(wǎng)站觀點,文章真實性請瀏覽者慎重核實!任何投資加盟均有風(fēng)險,提醒廣大民眾投資需謹(jǐn)慎!

網(wǎng)站簡介 - 聯(lián)系我們 - 營銷服務(wù) - XML地圖 - 版權(quán)聲明 - 網(wǎng)站地圖TXT
Copyright.2002-2019 寧夏資訊網(wǎng) 版權(quán)所有 本網(wǎng)拒絕一切非法行為 歡迎監(jiān)督舉報 如有錯誤信息 歡迎糾正