Bootloader:启动程序
OTA:网络升级,是 Bootloader 的一个重要功能。
Flash 分区
B 区:存放 Bootloader 程序
A 区:存放主程序
B 区要在A区前面,因为B区的大小是固定的,而A区的程序是变化的,如果A区在前,可能会覆盖掉B区的程序,造成Bootloader失效。
在线更新:板子上不存储要更新的APP,通过线连接的方式与上位机通信,实时写入,比如串口、CAN总线。
离线更新(脱机更新):程序事先写入板子上的外部FLASH、SD卡、EMMC等,单片机从这里面读取程序并更新。
这是两个工程
例程:
自定义传输协议
Ymodem 协议
跳转到指定地址执行
#define AppAddr 0x08100000 /* APP地址 */
static void JumpToApp(void)
{
uint32_t i=0;
void (*AppJump)(void); /* 声明一个函数指针 */
/* 关闭全局中断 */
DISABLE_INT();
/* 设置所有时钟到默认状态,使用HSI时钟 */
HAL_RCC_DeInit();
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
/* 使能全局中断 */
ENABLE_INT();
/* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */
AppJump = (void (*)(void)) (*((uint32_t *) (AppAddr + 4)));
/* 设置主堆栈指针 */
__set_MSP(*(uint32_t *)AppAddr);
/* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
__set_CONTROL(0);
/* 跳转到系统BootLoader */
AppJump();
/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
while (1)
{
}
}另一种:
static void Boot_vJumpToApp(uint32_t u32_appAddress)
{
uint32_t u32_jumpAddress;
pFunction JumpToApp;
if (((*(__IO uint32_t*)u32_appAddress) & 0x2FFE0000 ) == 0x20000000)
{
u32_jumpAddress = *(__IO uint32_t*) (u32_appAddress + 4);
JumpToApp = (pFunction)u32_jumpAddress;
__set_MSP(*(__IO uint32_t*)u32_appAddress);
JumpToApp();
}
}