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:统一汇编语言)