单片机BootLoader的通用实现方式(备份升级,永不挂机)
背景介绍
实现方式
分区划分
将整个flash分区化为为
- 参数区:存储升级过程状态标志位,升级信息,其他升级参数等
- boot区:存放BootLoader程序
- app区:存放app程序
- app备份区:存放app程序的备份
修改链接脚本
链接脚本的修改方式每个单片机都不一样,这里只是介绍一种通用的升级思路,具体修改方法自行百度
硬件相关驱动代码的实现
根据具体的单片机实现以下相关代码
- flash读写
- 复位:可以操作软件复位寄存器,也可以开启看门狗故意饿死狗实现复位
- 程序跳转:可以参考汇编中跳转到main的代码实现,或者使用C语言函数指针强制跳转
- 固件接收:一般是一种通讯接口,实现把固件接收下载,如串口、spi、网络等相关通讯接口
升级逻辑实现(重点)
- 通过上位机或其他CPU或者网络像app程序
为了BootLoader稳定可靠,采用以下逻辑实现
App程序中的操作:
App程序在空闲任务中将BootLoader参数区第一个字节(以下简称标志)清除,即置0,当收到opencpu发送的升级请求后,执行app程序备份操作,首先校验app分区和备份分区的md5值,如果不一致,将app主分区的应用程序完整的拷贝到备份区,之后将标志位设置为1,请求复位。
BootLoader程序操作:
BootLoader程序启动后判断参数时候为0,如果为零说明不需要升级,直接跳转到app主分区执行程序,为1则证明需要升级,执行相关的初始化操作同时将标志位设置为2开始执行升级程序,接收到的app二进制程序直接写入app主分区flash中,接收完毕后进行校验,若md5校验成功将标志位设置为3,表示尝试跳转到主分区执行,当BootLoader检测到标志位为3时,将标志位设置为2,尝试跳转到主分区执行,若执行成功,app程序会在空闲时间将标志位清除,若执行失败,引发看门狗复位后,BootLoader将检测到标志位2,开始异常处理,执行回滚操作,将备份分区的程序拷贝到主分区继续执行。
BootLoader逻辑状态转换表如下图所示
BootLoader状态标志 | 描述 BootLoader状态 | 标志改变 | 该状态下操作 |
---|---|---|---|
0 | 不需要升级直接跳转应用程序 | 0 / 1 | 进入应用程序运行正常设置标志为 0,等待发送升级指令,接收到上位机的升级指令后,先把当前app分区程序拷贝到备份分区,然后设置标志为 1,进入BootLoader升级 |
1 | 进入BootLoader程序开始升级 | 2 / 3 | 进入升级状态设置标志为 2,刷写校验通过后设置标志为 3 |
2 | 表示升级程序异常处理,如突然断电、主分区程序错误等,执行回滚 | 4 | 拷贝备份区程序到主程序分区并跳转到app |
3 | 尝试跳转到主分区 | 2 / 0 | 尝试跳转到主分区执行设置标志为 2,跳转到app程序执行成功,app程序设置标志为 0 |
4 | 回滚失败 | 1 | 进入BootLoader发送特殊指令,等待app写入。(该状态一般不会存在,作为异常处理) |