目录
背景:当嵌入式软件需要固件升级时,有时需要拆卸设备,较为麻烦,为方便升级,提供远程升级的功能,可通过网络或其他通讯接口传输固件进行升级。
系统分为两大模块:Bootloader和APP应用程序,系统复位后先运行Bootloader程序,此程序负责升级APP应用程序。Bootloader执行结束后跳至APP应用程序。APP负责接受新的APP程序。
下载固件流程:
- 将待升级的新固件命名为mcu.bin后通过产品支持的方式传输的SD卡中,可以是通过网络tftp传输,或者can通信传输,也可以直接拷贝到SD卡,取决于app自身所含有的功能。必须保证固件是完整的、功能正常的,可用于升级的,若固件不完整将导致升级固件后设备无法正常启动。
- 传输好固件后,需要通过下发升级指令置起需要升级的标志,协议可以自定,该标志存储在backup ram的起始位置处,backup ram复位不会丢失,仅断电会丢失,置好标志后,延时一会进行复位。
*(volatile int *)BKPSRAM_BASE = 1;
- 复位后将跳转到Bootloader的程序。
-
下载固件流程
Bootloader程序设计流程
- 读取升级标志位判断是否需要升级,若不需要升级直接跳转到app
- 若需要升级,打开sd卡里的mcu.bin文件,以512字节/包的方式进行固件对的读取和擦写,当读取的数据小于512字节,表明固件已经读取完毕,擦除完以后就可以跳转到app,使用新固件了。
普通工程改为APP工程的步骤
- 在keil工程里,需要修改app的flash起始地址和大小,默认起始地址是0x8000000,大小为0x100000,需根据flash的空间划分进行修改,例如Bootloader预留64k,那么app的起始地址就为0x8010000,Size改为:0xF0000。在keil里,打开Options for Target ‘target 1’对话框或者点击魔术棒,点击Target,找到IROM1,将0x8000000改为0x8010000,0x100000改为0xF0000
- 继续选择User标签页,勾选Run#1,在框里输入fromelf.exe --bin -o "$L@L.bin" "#L" ,该步骤是开启编译时生成bin文件
- 在main里,需要重映射中断向量表,使用如下语句
SCB->VTOR = FLASH_BASE | 0x10000; //偏移0x10000,需与步骤1中的工程配置保持一致
- 将升级标志清除,升级标志存储在backup ram里,需要先初始化一下,(stm32F7系列产品)添加并调用如下BKP_SRAM_Init函数进行初始化,再执行 *(volatile int *)BKPSRAM_BASE = 0xAAAABBBB;//清除升级标志,人为定义的特殊值,其值含义需与Bootloader一致。
void BKP_SRAM_Init(void)
{
/* 电源接口时钟使能 (Power interface clock enable) */
__HAL_RCC_PWR_CLK_ENABLE();
/* DBP 位置 1,使能对备份域的访问 */
HAL_PWR_EnableBkUpAccess();
/* 通过将 RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR) 中的 BKPSRAMEN 位置 1, 使能备份 SRAM 时钟 */
__HAL_RCC_BKPSRAM_CLK_ENABLE();
/* 应用程序必须等待备份调压器就绪标志 (BRR) 置 1,指示在待机模式和 VBAT 模式下会保持写入 RAM 中的数据。 */
HAL_PWREx_EnableBkUpReg();
}