STM32单片机DFU升级固件的实现和BKP备份寄存器的使用

最近用STM32F411做了一个小产品,为了方便以后升级固件和修复bug,所以需要考虑实现iap功能。由于产品对外只有USB和UART两个接口,考虑到多用户的通用性,所以选择了USB作为升级入口。主要过程参考了下面这篇文章(利用stm32cubemx实现USBDFU对芯片程序的更新升级),这里不详细描述实现过程,只分享一下自己移植过程遇到的一些问题和自己的一些实现思路供大家参考。
STM32F4系列的flash分区是这样的,这里我们使用前三个扇区划分Bootloader,第四扇区作为用户数据存储区,第五扇区以后划分给APP使用,当然,如果你有多个APP也可以给每个APP划分起始地址。
在这里插入图片描述
按照参考资料里面的方法,先设计Bootloader部分,这里我遇到了第一个问题,设计好刷入单片机后,PC上不显示,而是这样的
在这里插入图片描述
这里需要手动更新一下驱动,驱动的位置在的安装目录下,例如我的是

C:\Program Files (x86)\STMicroelectronics\Software\DfuSe v3.0.6\Bin\Driver

安装完成后显示如下,到这里Bootloader基本就设计完了
在这里插入图片描述
按照参考的资料中,Bootloader里面跳转至APP和进入DFU模式是通过一个按键来切换,因为我们的产品上只有一个USB接口和一个4Pin的串口,没有设计按键,所以这里我换了一个方式来实现切换,就是利用BKP备份寄存器来实现,实现思路是在在APP中,设计一条升级指令,用户通过USB向MCU发送升级指令后,APP中会对BKP寄存器0写入一个特殊的数字(例如0xbeef),然后让MCU重启。
由于BKP寄存器只要不断电,寄存器内的数据就不会改变(虽然我们的产品中没有设计纽扣电池来为BKP寄存器供电,但是MCU在重启中指不会掉电的,所以BKP寄存器数据依然是可用的)。
MCU重启后会进入Bootloader,读取BKP寄存器的寄存器0内的数据是否为0xbeef,如果不是,就跳转至APP,如果是,就进入DFU模式升级固件,升级完成后将寄存器0写为其他值(例如0x0000) 。
由于并没有找到DFU升级完成对标志位或者状态监测函数,所以这里用了一个简单的做法,就是MEM_If_Write_FS函数被调用,且1000ms内没有再次被调用,则判断升级完成。
这里要吐槽一些HAL库的,HAL库中没有设计BKP寄存器的操作函数,只有在RTC相关的函数中才有操作BKP寄存器的接口,所以这里我自己设计了一些操作函数。

/**

*/
void HAL_BKUPEnable(void){
	__HAL_RCC_PWR_CLK_ENABLE();
	HAL_PWR_EnableBkUpAccess();
}
/**

*/
void HAL_BKUPDisable(void){
	HAL_PWR_DisableBkUpAccess();	
}
/**

*/
void HAL_BKUPWrite(uint32_t BackupRegister, uint32_t Data)
{
  uint32_t tmp = 0U;
  /* Check the parameters */
  tmp = (uint32_t)(RTC) + 0x50; //RTC=0x4000 2800
  tmp += (BackupRegister * 4U);
  /* Write the specified register */
  *(__IO uint32_t *)tmp = (uint32_t)Data;
}
/**

*/
uint32_t HAL_BKUPRead(uint32_t BackupRegister)
{
  uint32_t tmp = 0U;
  /* Check the parameters */
  tmp = (uint32_t)(RTC) + 0x50; //RTC=0x4000 2800
  tmp += (BackupRegister * 4U);
  /* Read the specified register */
  return (*(__IO uint32_t *)tmp);
}

这里是参照了RTC相关函数中对BKP的操作实现的,这里有个小的疑惑,按照ST的介绍,BKP是16位的寄存器,但是这里似乎都是按照32位寄存器的操作方法在操作。
最后的最后,为了避免DFU升级固件失败导致APP无法启动,APP无法启动的情况下就没法通过发指令进入DFU模式的这个死锁,我们还是设计了IO口检测电平的方式来进入DFU模式,即在Bootloader代码中将串口做用到的两个IO配置为普通IO输入模式并上拉,Bootloader中检测到两个引脚中任意一个引脚为低电平就进入DFU模式,所以如果出现APP无法启动,只需要将串口的TX或RX短接到GND再上电就可以进入DFU模式重新升级固件了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值