Bootloader中斷向量重定位問題
1.Bootloader程序在內核Cortex-M0+內核中運行時需要進行地址跳轉執行應用程序主程序,此時就涉及到了中斷向量重定位問題,以下截圖為單片機啟動文件中的棧和堆空間大小分配以及中斷向量表的分配:
根據上圖可以看到,_initial_sp棧頂指針和向量表起始地址均未設置。
默認情況下,cortex-m0+內核認為該表位於零地址處,且各向量占用4 字節,因此每個表項占用4 字節。
中斷向量表里的中斷跳轉地址在編譯后就定下來了,SCB->VTOR向量可動態調整就是讓我們的程序運行后還能改變向量的跳轉地址。方法就是:在RAM重建一個中斷向量表,在想改變的位置重新賦值新的跳轉地址。
要想實現Flash程序跳轉和SRAM程序跳轉,第一步先設置SCB->VTOR向量,重置中斷向量表的起始地址(不是默認的0x00000000了),其中_DSB()為數據同步隔離、_ISB()為指令同步隔離(確保接下來的所有指令都使用新配置)。
以上為改變中斷向量表起始地址,經過_DSB()和_ISB()指令后接下來要給這些地址指針重新賦值,也就是在FlashLoader_ASM()和SRAMLoader_ASM()被調函數中重新配置MSP和PC的值。
以SJ_FLASH_BASE=0x10000000,SJ_SRAM_BASE=0x20000000為例:
0x10000000==1<<28 0x20000000==1<<29
以上兩個函數均是將SJ_FLASH_BASE或SJ_SRAM_BASE地址處存儲的值賦給SP,再將地址值偏移4字節后得到的地址里存儲的值給PC,
上面過程類似啟動文件中中斷向量表里提到的Reset_Handler,也是先給_initial_sp棧頂指針賦值中斷向量表起始地址,然后地址偏移4字節程序跳轉到啟動文件后面定義的Reset_Handler函數執行如下:
區別只不過是_main和SystemInit代表的是入口地址常量,而前者是直接操作地址值。
針對以上用到的匯編指令解析如下:
1. 跳轉指令BLX和BX、BL、B的區別,如下表所示:
2. LDR為最常用的偽指令(偽指令只在編譯程序時用到,由匯編器等開發工具決定),將32位立即數加載到寄存器中。
3. MOV和MOVS
MOVS R0, R1 ;將R1送到R0中,並更新APSR
MOV R0, R1 ;將R1送到R0中
4. LSLS和LSL指令區別(UAL:統一匯編語言)