1、生成Map文件
复制中断向量表前需要知道中断向量表的大小,可以通过编译生成的Map文件查看。
2、查看中断向量表大小
中断向量表的大小是固定的,与程序代码量无关,打开Map文件,直接搜索0x08000000,我使用的 MCU 是 STM32H743XIH6,中断向量表大小为 664 字节,即 MDK 编译生成的 Bin 文件,开始的 664 个字节是中断向量表
RESET 0x08000000 Section 664 startup_stm32h743xx.o(RESET)
!!!main 0x08000298 Section 8 __main.o(!!!main)
!!!scatter 0x080002a0 Section 52 __scatter.o(!!!scatter)
!!dczerorl2 0x080002d4 Section 90 __dczerorl2.o(!!dczerorl2)
!!handler_zi 0x08000330 Section 28 __scatter_zi.o(!!handler_zi)
3、读取中断向量表的内容,并直接放在指定的SRAM 地址处
// 中断向量表大小 664 字节
#define VECTOR_TABLE_SIZE 664
// 中断向量表复制到 SRAM 0x24001000 地址
u8 vector_table[VECTOR_TABLE_SIZE] __attribute__ ((at(0X24001000)));
// 读取 Flash 内容
// STMFLASH_Read(addr,(u32*)vector_table,VECTOR_TABLE_SIZE/4);
值得注意的是,STMFLASH_Read 函数不能读取 Flash 程序代码所在的空间,否则会出现异常
我这里的设计是 BootLoader 程序通过 Can 接收待升级的固件 Bin 文件(然后写入指定的 FLASH 地址处,在把前 664 字节数据读出来复制给 vector_table)并将前 664 个字节的中断向量表直接复制给 vector_table,即完成了中断向量表的复制到 SRAM 的 0x24010000
4、APP程序的设置
以上只是完成了,中断向量表的复制,还需要告诉 APP 程序中断向量表的位置,APP程序中添加如下代码。
SCB->VTOR = D1_AXISRAM_BASE|0x1000;
再运行 APP 程序的时候,使用的就是 SRAM 中的中断向量表了。
这样做的目的是,固件升级的时候,可以在 FLASH 中存放多个 APP 程序。