標(biāo)題: STM32F0系列MCU中斷向量表的重映射 [打印本頁]

作者: 51黑er    時(shí)間: 2015-11-9 14:48
標(biāo)題: STM32F0系列MCU中斷向量表的重映射
    最近使用了一款Cortex-M0內(nèi)核的芯片STM32F030CC,發(fā)現(xiàn)它中斷向量表的重映射方法與STM32F10x系列的有所區(qū)別,在這里記錄與分享一下。
     由于需要通過IAP進(jìn)行固件升級,所以芯片的FLASH里面要燒錄兩份代碼:一個(gè)Boot loader, 一個(gè)用戶應(yīng)用程序。理所當(dāng)然的,在用戶應(yīng)用程序中,必須得重新映射中斷向量表。
     可是在ST提供的固件庫里,我卻沒有發(fā)現(xiàn)類似于stm32f10x固件庫中的voidNVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)接口。
     瀏覽了一下Cortex-M0的Programmingmanual,原來M0并沒有SCB->VTOR這個(gè)寄存器,難怪ST的庫里沒有提供NVIC_SetVectorTable這個(gè)接口。
     這下要怎么辦?在網(wǎng)絡(luò)上搜索了一下,受到網(wǎng)友findaway123這篇文章的啟發(fā),我在STM32F030CC的Reference manual中找到以下說明:
     Physicalremap
  Once the boot mode is selected, the application software canmodify the memory accessible in the code area.This modification isperformed by programming the MEM_MODE bits in the SYSCFGconfiguration register 1 (SYSCFG_CFGR1). Unlike Cortex? M3 and M4,the M0 CPU does not support the vector table relocation. Forapplication code which is located in a different address than0x0800 0000, some additional code must be added in order to be ableto serve the application interrupts. A solution will be to relocateby software the vector table to the internal SRAM:
  ? Copy the vector table from the Flash (mapped at the base of theapplication load address) to the base address of the SRAM at 0x20000000.
  ? Remap SRAM at address 0x0000 0000, using SYSCFG configurationregister 1.
  ? Then once an interrupt occurs, the Cortex?-M0 processor willfetch the interrupt handler start address from the relocated vectortable in SRAM, then it will jump to execute the interrupt handlerlocated in the Flash.
  This operation should be done at the initialization phase of theapplication. Please refer to AN4065 and attached IAP codefrom www.st.com for more details.
  OK,解決方法找到了!

  在用戶應(yīng)用程序中,按照以上方法,添加以下兩行代碼:
    memcpy((void*)0x20000000, (void*)0x08004000, VECTOR_SIZE); SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
   其中,0x2000 0000是SRAM的起始地址,這個(gè)不需要改動(dòng)。
   而之后的兩個(gè)參數(shù)需要根據(jù)實(shí)際情況作出修改。0x08004000是應(yīng)用程序的起址地址,從這里開始的VECTOR_SIZE字節(jié),存放是的應(yīng)用程序的中斷向量表。VECTOR_SIZE是指中斷向量表的大小,具體多大可以在startup.s文件里計(jì)算得到。以下以startup_stm32f030.s為例作說明:


  我們只需關(guān)注其中的一小部分。從29行開始,直到75行,每一個(gè)DCD都代表一個(gè)中斷向量(所謂中斷向量,說得明白點(diǎn),其實(shí)就是某個(gè)中斷服務(wù)程序的入口地址)。例如第74行的:
  DCD     USART1_IRQHandler              ; USART1
  這里的“USART1_IRQHandler"其實(shí)就是UART1中斷服務(wù)程序USART1_IRQHandler這個(gè)函數(shù),同時(shí),它也代表這個(gè)函數(shù)的入口地址。
  以上代碼即定義了這樣一張表,這張表包括45個(gè)元素,每個(gè)元素是一個(gè)長度為4字節(jié)的地址。除了第一個(gè)地址是SP(堆棧指針)外,其它的地址都是某個(gè)中斷服務(wù)程序的入口地址。
  那么,回到我們要解決的問題上來,之前memcpy函數(shù)中的第三個(gè)參數(shù)VECTOR_SIZE,針對本例,就應(yīng)該是45*4=180(0xB4)個(gè)字節(jié)。

  在執(zhí)行完以上兩行代碼后,若發(fā)生中斷,CPU就會(huì)去SRAM(即0x2000 0000處)取中斷向量了,所以,以0x20000000作為起始地址之后的VECTOR_SIZE個(gè)字節(jié)就不能被改動(dòng)了。為了達(dá)到這VECTOR_SIZE個(gè)字節(jié)不被修改的目的,如下兩種方法可以實(shí)現(xiàn)。
  ?在工程文件內(nèi)修改SRAM的起始地址及長度,如下圖
  
  ?如果使用了分散加載文件,則在分散加載文件中修改SRAM的起始地址及長度也能達(dá)到目的。

  至此,STM32F0系列Cortex-M0內(nèi)核芯片中斷向量表重映射的問題已解決。


作者: goalken    時(shí)間: 2017-11-6 14:33
厲害咯,大神!在這里找到了STM32F0中斷生定向的答案!感謝樓主!
作者: kong1990730    時(shí)間: 2018-8-8 10:56
memcpy((void*)0x20000000, (void*)0x08004000, VECTOR_SIZE); SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
這兩行代碼是寫在 哪個(gè)文件中
作者: shede    時(shí)間: 2019-11-19 11:33
講得很詳細(xì),最近弄這個(gè)網(wǎng)上都是M3系列的例程,在這里終于看懂了M0內(nèi)核的中斷向量表的重映射配置,感謝大神
作者: cmyldd    時(shí)間: 2023-5-24 16:03
m0  和 m1 有點(diǎn)不一樣的, 多謝奉獻(xiàn)!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1