国产午夜男女在线|欧美日本一道高清国产|亚洲日韩乱码中文字幕|麻豆国产97在线精品一区|日韩一区2区三区另类图片|亚洲精品国产99在线观看|亚洲国产午夜福利精品大秀在线|一级做a爰片性色毛片免费网站

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

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

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

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

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

VTOR是arm內(nèi)核的一個(gè)寄存器,叫做中斷向量偏移量寄存器。當(dāng)系統(tǒng)上電啟動(dòng)的時(shí)候CPU會從先找到中斷向量表的位置,然后從表中找到復(fù)位中斷Reset_Handler,而main函數(shù)的執(zhí)行實(shí)際上就是在復(fù)位中斷函數(shù)中的。如下匯編代碼就是復(fù)位中斷服務(wù)函數(shù),該函數(shù)在啟動(dòng)文件中定義。在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處理器啟動(dòng)到執(zhí)行main的一個(gè)大概流程。再回歸正題繼續(xù)探討這個(gè)VTOR。當(dāng)來一個(gè)中斷時(shí),cpu就會從0x0000000+VTOR位置找到中斷向量表,然后再查表跳轉(zhuǎn)到對應(yīng)的中斷服務(wù)函數(shù)去執(zhí)行。所以你代碼里面存在多份中斷向量表是可以的,只需要?jiǎng)討B(tài)改變VTOR的值就可以了。

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

APP的中斷向量放在flash中:

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

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

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

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

中斷向量放在RAM中:

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

為什么這樣做,因?yàn)榍懊嫖覀兲岬竭^CPU默認(rèn)會認(rèn)為0x00000000處放的就是向量表。那么我們換種思路可以把RAM的地址映射到0x00000000處。這個(gè)通過配置SYSCFG寄存器的MEM_MODE就可以把RAM地址映射到0x00000000處。

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

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

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

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

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

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

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

__align(256) uint32_t vector_t[48];

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

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

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

關(guān)于0X00000000地址

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

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

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

(正文已結(jié)束)

推薦閱讀:每日江蘇

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

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