1.初衷
记录知识,分享心得
2.背景
当下很多应用场景中,都需要现场程序更新升级,来更新产品功能或者修复已知的程序bug,以往我们对电子产品的升级都是借助电脑和升级工具通过有线的方式进行程序升级,比如借助下载器通过SWD或者JTAG方式进行程序烧录到电路板或者通过串口ISP,这些方式费时费力,尤其针对复杂的现场环境,携带电脑等工具极其不便利,故引出此篇文章,只需一个U盘,即可实现现场程序的快速升级。
3.USB HOST IAP介绍
如上图,程序升级的本质是在一块flash内存上,分出两块存储区,第1块存储区我们称之为Bootloader区,第2块存储区称之为APP应用区。上图中的0x08000000-0x0801FFFF指的是第1块存储区,0x08020000-0x082FFFFF指的是第2块存储区,我们可以在第2块存储区运行我们平常的主程序,在主程序中检测USB是否有插入,如果USB有插入,我们可以设置去读取U盘中事先放好的升级程序所需要的文件(bin文件),将程序升级文件读取出之后放在外部的flash中,然后使用系统复位函数,将程序复位,那么程序会从第1块存储区开始运行,我们需要做的就是在第1块存储区的代码中实现检测是否有新的程序写入了外部flash,如果有,我们就将外部flash所存储的程序读取写入到第2块存储区,写入完毕后我们利用程序跳转指令将正在运行的程序从第1块存储区跳转到第2块存储区开头去运行已升级后的APP主程序,至此完成程序升级。
4.两个程序的配置
Bootloader程序:
APP程序:
如上图,选用的是GD32F305VE芯片, Boatloader程序占用32KB,APP程序占用480KB,共计512KB。
5.结尾
第一次写文章且本人资历尚浅,只想把这些知识做记录以待日后翻阅也怀一颗分享知识之心,可能表述不周,望广大网友提出建议和指出错误。
6.代码
完整两个工程代码可私信我私发,无法打包上传,以下为部分代码实例,几乎所有芯片用USB升级程序的思想都大同小异。
BootLoader程序:
int main(void)
{
unsigned short indx,indx1;
/* 初始化LED */
LED_GPIO_Init();
TIM_SysFault_GPIO_Config();
LCD_Init();
/* 初始化调试串口 */
USART_Config();
Usart_SendString("\r\n BootLoader Code Start");
SPI_Flash_Init();
/* flash unlock */
FLASH_LAYER_FlashUnlock();
// 读出程序是否需要更新标志位
SPI_Flash_Buffer_Read(ReadBuff,USERPRO_FLAG_ADDRESS_FLASH,PAGE_SIZE);
Sector_Count = ReadBuff[5]; // 读出上次下载的程序占用了多少扇区
if((ReadBuff[