嵌入式:Bootloader跳转到固件流程
·
MCU通过Bootloader实现了接收、解析、刷写并校验完上位机发送的固件(.bin)后,需要跳转到固件程序
首先,我们先复习一下main()函数的跳转步骤
一、MCU 上电后 main 函数的启动
MCU启动核心是中断向量表 _Vectors ,其中存了 MSP、Reset_Handler、中断函数入口地址
其中Reset_Handler里包含了跳转main动作
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
固件APP的.bin文件开头是 startup.s 中定义的中断向量表。Bootloader 跳转 APP 时,需要先找到 APP 固件在 Flash 中的起始地址,也就是 APP 向量表地址
二、Bootloader 跳转固件流程
2.1 关闭Bootloader外设以及中断
led_off(led1);
TIM_DeInit(TIM6);
USART_DeInit(USART1);
USART_DeInit(USART3);
NVIC_DisableIRQ(TIM6_DAC_IRQn);
NVIC_DisableIRQ(USART1_IRQn);
NVIC_DisableIRQ(USART3_IRQn);
2.2 跳转程序
step1:跳转固件时,我们首先得更新中断向量表的位置(固件中断向量表存放在刷写.bin文件的开头)
SCB->VTOR 是 Cortex-M 内核中的 向量表偏移寄存器,用于指定当前程序使用哪一张中断向量表。
如果不修改 SCB->VTOR,即使程序已经跳转到 APP,发生中断时 CPU 仍然会去 Bootloader 的中断向量表中查找中断服务函数,这会导致中断执行错误,甚至程序跑飞。
举个例子:在进入固件主程序的中断时,可能跑偏到Bootloader的中断配置
void USART3_IRQHandler(void)
{
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
if (rx_callback)
{
uint8_t data = (uint8_t)USART_ReceiveData(USART3);
rx_callback(&data, 1);
}
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
}
上述为Bootloader串口3中断函数实现数据的接收并写入环形缓冲区,而固件APP串口3中断函数可能实现其他功能,因此需要更新SCB->VTOR。
step2:配置MSP、PC指针指向固件的中断向量表
//step1. 更新中断向量表位置
SCB->VTOR = APP_VTOR_ADDR; //APP_VTOR_ADDR = 0x08010000;
//step2. 程序跳转
extern void JumpApp(uint32_t base);
JumpApp(APP_VTOR_ADDR);
//跳转程序
JumpApp PROC
LDR SP, [R0, #0]
LDR PC, [R0, #4]
ENDP
END
这里跳转程序采用汇编语言,更新MSP、PC栈顶;下一步进入固件的中断向量表→Reset_Handle →SystemInit→main(),继而进入了固件的主程序
更多推荐


所有评论(0)