STM32的內(nèi)存地址映射與IAP下載
stm32的flash地址起始于0x08000000,結(jié)束地址是0x080000000加上芯片實(shí)際的flash大小,不同的芯片flash大小不同。RAM起始地址上0x200000000,結(jié)束地址是0x20000000加上芯片的RAM大小。STM32將外設(shè)等都映射為地址的形式,對(duì)地址的操作就是多外設(shè)的操作。
stm32的外設(shè)地址從0x40000000開(kāi)始,可以看到在庫(kù)文件中,是通過(guò)基于0x40000000地址的偏移量來(lái)操作寄存器以及外設(shè)的。
一般情況下,程序文件從0x08000000地址寫(xiě)入,這是STM32開(kāi)始執(zhí)行的地方,0x08000004是stm32的中斷向量表起始地址。
在使用keil編程的過(guò)程中,其編程地址的設(shè)置一般是這樣:
即程序程序的寫(xiě)入地址從0x08000000(數(shù)好零的個(gè)數(shù))開(kāi)始的,其大小為0x80000也就是512K的空間,換句話說(shuō)就是告訴編譯器flash的空間是從0x08000000-0x08080000,RAM的地址從0x20000000開(kāi)始,大小為0x10000也就是64K的RAM。這與STM32的內(nèi)存地址映射關(guān)系是對(duì)應(yīng)的
M3復(fù)位后,從0x08000004取出復(fù)位中斷的地址,并且跳轉(zhuǎn)到復(fù)位中斷程序,中斷執(zhí)行完之后會(huì)跳到我們的main函數(shù),main函數(shù)里邊一般是一個(gè)死循環(huán),進(jìn)去后就不會(huì)再退出,當(dāng)有中斷發(fā)生的時(shí)候,M3將PC指針強(qiáng)制跳轉(zhuǎn)回中斷向量表,然后根據(jù)中斷源進(jìn)入對(duì)應(yīng)的中斷函數(shù),執(zhí)行完中斷函數(shù)之后,再次返回main函數(shù)中。大致的流程就是這樣。
下面說(shuō)正題,IAP下載方式:
IAP下載的原理就是在M3中運(yùn)行有一個(gè)程序,這個(gè)程序的起始地址是從0x08000000開(kāi)始的,也就是說(shuō)M3復(fù)位后執(zhí)行的就是這個(gè)程序,稱(chēng)之為bootloader吧,一般這個(gè)程序的作用是接收APP程序,就是我們想要下載到M3上的程序,就好比給手機(jī)下載新的APP程序一樣,下載完成之后就可以跳轉(zhuǎn)APP的地址開(kāi)始執(zhí)行新的APP程序。當(dāng)有APP程序發(fā)送到M3上之后,bootloader程序就開(kāi)始接收并保存在RAM中(其實(shí)保存在哪里是由自己決定的,就看你程序怎樣設(shè)計(jì)了),程序下載完成之后,將PC指針指向程序的開(kāi)始地址就可以執(zhí)行該程序了,但是還有其他的要設(shè)置,那就是中斷向量表的偏移量需要根據(jù)APP程序的起始地址設(shè)置。
例如,在bootloader程序中,程序的起始地址是這樣設(shè)置的:0x08000000 ,size=0x80000。 RAM從地址:0x2000F800開(kāi)始,size=0x800。0x20000000-0x2000F800用來(lái)作為緩存,接收APP程序,接收完APP程序后將程序復(fù)制到flash中,就是最終執(zhí)行程序的時(shí)候,程序要已經(jīng)寫(xiě)在flash中。
APP程序中,我選擇將APP程序燒寫(xiě)在flash中,因?yàn)閎ootloader也會(huì)占用flash的空間,APP程序的存儲(chǔ)地址從0x08010000開(kāi)始,size=0x70000,也就說(shuō)0x08000000-0x08010000這段空間內(nèi)存放的是bootloader程序。接下來(lái)就是中斷向量表的設(shè)置:因?yàn)锳PP程序的起始地址是0x08010000,所以偏移量為10000,使用語(yǔ)句SCB->VTOR = FLASH_BASE " 0x10000;設(shè)置中斷向量表的偏移量。
設(shè)置好之后,將bootloader程序下載到板子上,復(fù)位運(yùn)行程序,接著下載bin文件程序,要運(yùn)行bin文件,將PC指針指向BIN文件的開(kāi)始地址就可以了,也就是指向0x08010000.
APP程序也可以直接運(yùn)行在RAM中,原理和上邊是一樣的,就是程序的起始地址不一樣了,還有一點(diǎn)就是,既然程序放在了RAM中運(yùn)行,那么設(shè)置RAM要注意地址,一部分是bootloader運(yùn)行的RAM,一部分是APP程序存放的空間,還有一部分是APP程序運(yùn)行需要的RAM。
bootloader接收bin文件的時(shí)候,我將存放地址定義成USART_RX_BUF[USART_REC_LEN] __attribute__ ((at(0X20001000))),也就是接收到的APP程序開(kāi)始地址是0x20001000
在RAM運(yùn)行APP的設(shè)置如下:
設(shè)置好之后下載bin文件,運(yùn)行方式和上邊是一樣的。
本人菜鳥(niǎo),記錄一下,順便把學(xué)到的知識(shí)梳理一下,就寫(xiě)了這個(gè),如有錯(cuò)誤歡迎大神指出!





