當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]1 前言在使用F0的片子在增加IAP后,我們經(jīng)常發(fā)現(xiàn),原來的APP必須增加一段代碼,將中斷向量表從內(nèi)部FLASH拷貝到SRAM后再執(zhí)行REMAP到SRAM,這樣操作后APP才能正常運(yùn)行,這一過程一直困擾著蝶粉們,為什么需要這樣呢?本

1 前言

在使用F0的片子在增加IAP后,我們經(jīng)常發(fā)現(xiàn),原來的APP必須增加一段代碼,將中斷向量表從內(nèi)部FLASH拷貝到SRAM后再執(zhí)行REMAP到SRAM,這樣操作后APP才能正常運(yùn)行,這一過程一直困擾著蝶粉們,為什么需要這樣呢?本文將針對這一問題為大家解惑。

2 問題詳細(xì)描述

比如F0的下面這部分代碼:

#defineAPPLICATION_ADDRESS(uint32_t)0x08004000/*Privatemacro-------------------------------------------------------------*//*Privatevariables---------------------------------------------------------*/#if(defined(__CC_ARM))__IOuint32_tVectorTable[48]__attribute__((at(0x20000000)));#elif(defined(__ICCARM__))#pragmalocation=0x20000000__no_init__IOuint32_tVectorTable[48];#elifdefined(__GNUC__)__IOuint32_tVectorTable[48]__attribute__((section(".RAMVectorTable")));#endifintmain(void){uint32_ti=0;HAL_Init();/*Configurethesystemclockto48MHz*/SystemClock_Config();/*RelocatebysoftwarethevectortabletotheinternalSRAMat0x20000000***//*CopythevectortablefromtheFlash(mappedatthebaseoftheapplicationloadaddress0x08004000)tothebaseaddressoftheSRAMat0x20000000.*/for(i=0;i<48;i++){VectorTable[i]=*(__IOuint32_t*)(APPLICATION_ADDRESS+(i<<2));}/*EnabletheSYSCFGperipheralclock*/__HAL_RCC_SYSCFG_CLK_ENABLE();/*RemapSRAMat0x00000000*/__HAL_SYSCFG_REMAPMEMORY_SRAM();/*Addyourowncodehere...*///…}123456789101112131415161718192021222324252627282930313233343536373839123456789101112131415161718192021222324252627282930313233343536373839

如上所示,在沒有加入IAP之前這部分代碼不需要的,而加入IAP后,這部分代碼在F0中就必須添加了,不然APP會(huì)運(yùn)行部正常! 從代碼中可以看出,增加的代碼執(zhí)行了從內(nèi)部FLASH中拷貝中斷向量表到內(nèi)存,然后重映射SRAM,可是,蝶粉們不禁要問,為什么要這么操作?這個(gè)又是什么原因造成的?

3 原因分析
3.1 重映射

在搞懂這個(gè)問題之前我們首先先來看看什么是重映射。例如F072的參考文檔張SYSCFG寄存器的介紹,如下圖:

MEM_MODE的介紹如下:

從以上內(nèi)容我們可以得到以下信息:
1. MEM_MODE的值在上電后有BOOT0,BOOT1的狀態(tài)值決定。
2. MEM_MODE的值決定了哪個(gè)內(nèi)存映射到地址0x0000 0000
也就是說:
? 當(dāng)MEM_MODE =00/10時(shí),Main Flash映射到地址0x0000 0000,即地址0x0800 0000映射到0x0000 0000.
? 當(dāng)MEM_MODE =01時(shí),System Flash映射到地址0x0000 0000,也就是芯片自帶的Bootloader代碼部分會(huì)映射到地址0x0000 0000,即0x1FFF C800映射到地址0x0000 0000.
? 當(dāng)MEM_MODE =11時(shí),Embeded SRAM映射到地址0x0000 0000,也就是內(nèi)存地址0x2000 0000映射到地址0x0000 0000.
3. 經(jīng)過映射后,系統(tǒng)訪問地址0x0000 0000地址,就相當(dāng)于直接訪問映射的地址,如0x0800 0000.
4. 由BOOT0,BOOT1的狀態(tài)決定MEM_MODE的值,進(jìn)而決定哪個(gè)地址映射到地址0x0000 0000,這一過程我們稱之為映射。默認(rèn)映射是系統(tǒng)自動(dòng)完成的,并由BOOT0,BOOT1的狀態(tài)決定。
5. MEM_MODE位是RW的,也就是說可以修改的,如果修改其中,也就會(huì)相應(yīng)的修改映射到0x0000 0000的地址,這一修改的過程,我們就叫其為重映射。重映射是通過用戶代碼通過修改MEM_MODE的值來完成的。

3.2 系統(tǒng)啟動(dòng)

從STM32F072的參考手冊的2.5章,我們可以看到如下內(nèi)容:

從以上內(nèi)容我們可以得到以下有用信息:
1. 在復(fù)位啟動(dòng)后,系統(tǒng)在系統(tǒng)時(shí)鐘的第4個(gè)上升沿根據(jù)BOOT0,BOOT1的配置獲取其值,也就是存儲(chǔ)到寄存器SYSCFG_CFGR1的MEM_MODE位上,根據(jù)前面3.1的信息可知,這里進(jìn)一步確定了0x0000 0000的映射地址。這一過程是系統(tǒng)自動(dòng)完成的。
2. 在系統(tǒng)啟動(dòng)后,CPU從地址0x0000 0000獲取棧頂?shù)刂?,然后?x0000 0004開始執(zhí)行代碼。換句話說,由于0x0000 0000被映射了其他地址,獲取棧頂與執(zhí)行實(shí)際上都是從映射的地址上實(shí)施的。也就是從映射的地址開始執(zhí)行代碼,比如從地址0x08000 0004開始執(zhí)行代碼(如Mian Flash映射),比如0x1FFF C804(如System Flash映射,即BootLoader啟動(dòng)).
于是,我們簡單整理下系統(tǒng)的整個(gè)啟動(dòng)流程:
-> 系統(tǒng)復(fù)位
-> CPU在系統(tǒng)時(shí)鐘的第4個(gè)上升沿根據(jù)BOOT0,BOOT1的配置確定寄存器SYSCFG_CFGR1的MEM_MODE的值
-> MEM_MODE進(jìn)一步?jīng)Q定哪個(gè)地址(Main Flash,System Flash,SRAM)映射到地址0x0000 0000.
-> CPU從地址0x0000 0000獲取棧頂,從0x0000 0004開始執(zhí)行代碼,也就是從映射地址獲取棧頂,從映射地址+4的地方開始執(zhí)行代碼。
->映射地址+4對于著復(fù)位中斷例程(如0x08000 0004),也就是系統(tǒng)一開始就執(zhí)行Reset_Handler,進(jìn)而運(yùn)行SystemInit然后進(jìn)入到main函數(shù),就這樣,整個(gè)代碼啟動(dòng)完成。

接下來就是中斷產(chǎn)生于中斷響應(yīng)了。

3.3 中斷與中斷向量表

從ARM官網(wǎng)上的信息得知(http://infocenter.arm.com/help/index.jsp),在Coretext-M3與Coretext-M4核中,在System Control Block中存在一個(gè)向量表偏移量寄存器 VTOR(0xE000ED08),系統(tǒng)產(chǎn)生中斷后,內(nèi)核通過這個(gè)寄存器的值來找到中斷向量表的地址,進(jìn)而執(zhí)行中斷例程代碼,當(dāng)然,此寄存器的值是可以修改的,它的默認(rèn)值為0。實(shí)際上在大部分的M3和M4的工程中,一般都是在SystemInit函數(shù)中對此寄存器的值進(jìn)行設(shè)置,當(dāng)此之前,它的值為默認(rèn)值0,由于映射關(guān)系,實(shí)際上就是指向映射地址,比如0x0800 0000. 如下圖所示:

但是,由于STM32F0XX采用的是M0核,它是沒有這個(gè)VTOR寄存器的,那么它又是怎么找到中斷向量表的地址的呢?同樣在ARM官網(wǎng)上我們找到如下信息:

也就是說,對于M0來說,中斷向量表的地址固定在地址0x0000 0000上!
對此,我們也可以這么理解,將M0理解成M3/M4的特殊情況,M0假設(shè)也存在VTOR這么一個(gè)虛擬寄存器,只不過它的值不能修改,固定為0罷了,而M3/M4的這個(gè)VTOR寄存器一開始時(shí)它的值也是為默認(rèn)值0,只不過在程序運(yùn)行到SystemInit()函數(shù)后,在代碼中明確對其進(jìn)行了修改。

我們整理下STM32F0XX中斷的調(diào)用過程:
-> 產(chǎn)生中斷
-> CPU固定到地址0x0000 0000上找中斷入口函數(shù),由于映射關(guān)系,實(shí)際上是在從映射地址上尋找。
-> 找到并執(zhí)行中斷例程

此時(shí),可以回到我們一開始的問題上來了.

3.4 回到問題分析3.4.1 從IAP跳轉(zhuǎn)到APP的過程分析

從IAP跳轉(zhuǎn)到APP時(shí)到底發(fā)生了什么呢?首先我們來看看這個(gè)跳轉(zhuǎn)代碼:

/*Testifusercodeisprogrammedstartingfromaddress"APPLICATION_ADDRESS"*/if(((*(__IOuint32_t*)APPLICATION_ADDRESS)&0x2FFE0000)==0x20000000){/*Jumptouserapplication*/JumpAddress=*(__IOuint32_t*)(APPLICATION_ADDRESS+4);JumpToApplication=(pFunction)JumpAddress;/*Initializeuserapplication'sStackPointer*/__set_MSP(*(__IOuint32_t*)APPLICATION_ADDRESS);JumpToApplication();}12345678910111234567891011

如上,首先測試APP地址是否存在用戶代碼,如果存在,則首先將APPLICATION_ADDRESS + 4,作為跳轉(zhuǎn)地址,然后從APPLICATION_ADDRESS取棧頂并賦值給SP寄存器,最后跳轉(zhuǎn)。

于是我們可以得出結(jié)論:
跳轉(zhuǎn)代碼后,PC指針變了,SP棧指針也修改了,但是,中斷向量表的位置并沒有修正為APP的中斷向量表位置,還是采用IAP的中斷向量表位置。如果此時(shí)系統(tǒng)產(chǎn)生中斷,CPU還會(huì)固定從0x0000 0000地址中去找中斷入口,由于從IAP到APP,內(nèi)存映射并沒有改變,因此,實(shí)際上還是從0x0800 0000上去找中斷入口,也就是還是在IAP的中斷向量表上尋找,繼續(xù)執(zhí)行IAP的中斷例程,進(jìn)而引發(fā)hard fault,這顯然不是我們想要的。

3.4.2 問題分析

這里的關(guān)鍵是,如何將中斷向量表的尋找位置從0x0800 0000修改到0x0800 3000(假設(shè)為APP的地址)? 從之前的分析我們可以得出有兩種方法:
1 修改寄存器VTOR的值
2 內(nèi)存重映射
M3/M4核的MCU顯然采用了第一種方法,因此,在M3/M4的MCU上,即使添加了IAP,也不需要增加本文第二章所描述的代碼。而這部分代碼,正是M0采用的第二種方法,也是唯一可以修改尋找中斷向量方式的方法。

通過將SRAM

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉