本帖最后由 香水城 于 2017-8-17 14:38 编辑
【实战经验】STM32F09x不使用BOOT脚实现System Bootloader升级代码
前言
众所周知,使用STM32 时,当需要使用System Memory 中的Bootloader 进行代码升级的时候,需要将BOOT0 脚拉高,复位后才能进入Bootloader 程序,使用Flash Loader Demonstrator 等工具进行串口烧写升级。这就需要在BOOT0 这个引脚上留出按键或者是跳线脚。但是,STM32F09x 具有一项新的特性,使不必使用BOOT 脚而进行串口升级成为可能。我们来共同探讨一下。
问题
某客户在其产品的设计中,使用了STM32F091RCT6,产品在出厂后将来可能由于功能的升级需要升级代码。由于外观的需要,客户不希望留一个用于升级的按键或是跳线槽在外边。希望能够是通过接收串口命令来实现启动升级,又希望能够直接使用System Memory 中的Bootloader 进行代码升级。
调研
1.认识一下STMF09x 和STM32F04x 在Boot Configuration 中的新特性
打开参考手册RM0091,翻到Boot Configuration 那一节,我们可以看到Table 3 中对Boot Mode 进行了描述,如下:
从表格中,我们先来看一下第1 条注释:
“Grey options are available on STM32F04x and STM32F09x devices only.”
意思是说,灰色部分对STM32F04x 和STM32F09x 是有效的。也就是说,除了BOOT1 是在Option Byte 中的nBOOT1 配置之外,STM32F04x 和STM32F09x 甚至可以将BOOT0 通过Option Byte 中的nBOOT0 来配置,只要将Option Byte 中的BOOT_SEL 位配置为0。这使得纯粹使用软件来实现进入System Memory 中的Bootloader 来进行串口升级成为可能。
2.方案设计
既然STM32F04x 和STM32F09x 甚至可以将BOOT0 通过Option Byte 中的nBOOT0 来配置,那么基本的思路就是:
1) 在用户代码中,设置进入串口升级的条件(比如说使用复合按键,或者接收到串口发来的一串命令,等等);一旦条件成立,就将Option Byte 中关于BOOT 的配置设置为:BOOT_SEL=0(BOOT0 信号由nBOOT0 选项位定义),nBOOT1=1 & nBOOT0=0。然后进行复位,重载Option Byte,这个时候系统就会进入System Memory 中去运行Bootloader。
2) 此时,打开Flash Loader Demonstrator,可以进行下载,在下载之前我们要设置在烧写完程序后从Bootloader 跳转到用户代码,因为我们需要在用户代码中去将BOOT 的配置修改为从Main Flash memory 启动。如果不这么做,那么每次复位后都将从System memory 启动。
3) 从第二步可以看到,我们还需要在用户代码的最前面加入判断,如果BOOT 的配置不是从Main Flash memory 启动的话,必须对Option Byte 进行改写,将BOOT 的配置设置为从Main Flash memory 启动:BOOT_SEL=0(BOOT0 信号由nBOOT0 选项位定义),nBOOT1=1 & nBOOT0=1。
从这个思路出发,我们可以得到需要设计的流程图。
程序的流程图如下:
当进入串口升级的条件成立时,其流程如下:
实验
1.设计目标
使用NUCLEO-F091RC 来实现此实验。空片进行第一次烧写时使用SWD 进行烧写,之后所有的.hex 文件再次烧写都将使用Flash Loader Demonstrator 进行下载。不使用BOOT0 脚。由于只是实验,这里用按下USER 按键来代表进入串口烧写的条件,用户代码运行LD2 闪烁的功能。
2.程序设计
main()主程序如下:
我们可以看到,其实其整个过程与BOOTCONF_User()非常地像,唯独有两个区别:
1) 没有判断当前的BOOT 配置,并且在更新USER 时只是将nBOOT0 清零而已。因为在用户代码的最开始,我们已经保证了,BOOT 的配置一定是从Main Flash memory 启动,所以要切换到从System memory 启动,仅需要将nBOOT0 清零。
2) Option Bytes 更新并验证后,并没有调用FLASH_OB_Launch()。因为我们把它放在中断程序里头了。
程序要点到这里就已经很清楚了。此程序仅为实验用,所以对于出错处理和代码优化,可根据实际应用自行处理。
3.实验步骤
下面我们来进行实验:
1) 我们将程序编译生成的的.hex(我们将其命名为1.hex)通过SWD 接口,使用STM32 ST-LINK Utility 烧写到NUCLEO_F091RC 后,可以看到STM32F091RC 正在欢快地运行1.hex,闪烁着LD2。关闭STM32 ST-LINKUtility。
注:1.hex 是慢闪烁现象
2) 回到程序中,将main()函数中主循环的“Delay(0xAFFFF);”修改为“Delay(0xFFFF);”,重新编译生成.hex 文件,
我们将其命名为2.hex。
注:2.hex 是快闪烁现象
3) 现在我们要开始进行串口升级了。按下USER 按键,发现LD2 不再闪烁了,程序已经进入System memory 运行Bootloader 了。
4) 打开Flash Loader Demonstrator,做以下的配置:
5) 点“Next”进入下一个界面,再点“Next ”再进入下一个界面,再点“Next ”进入下一个界面,我们在这个页面中选择下载代码“Download to device”,导入刚才编译生成的2.hex,选中“Jump to the user program ”,意思就是通过串口烧写完毕后,直接跳到用户代码去运行。如图:
6) 点击“Next”进行代码烧写。烧写成功后,我们就可以看到LD2 更加欢快地闪烁了,证明我们的烧写是成功的。按下RESET 按键,也能正常运行代码;断电后再上电,也正常运行。
到这里,我们的实验成功了,我们可以重复3)~6)步骤来反复烧写1.hex 和2.hex,体验这个串口升级的方便性,再也不用去拔跳线插跳线了。
结论
由于STM32F04x 和STM32F09x 可以将BOOT0 通过Option Byte 中的nBOOT0 来配置,这个新特性决定了我们可以很方便地实现不使用BOOT 脚就直接从System memory 中的Bootloader 进行代码升级。非常地方便。
处理
此实验证明了“STM32F04x 和STM32F09x 不使用BOOT 脚实现System Bootloader 升级代码”的可行性。但只是实验,客户可自行处理错误情况和代码优化。此外,此实验用按下USER 按键来激活串口烧写,客户可自行根据应用来修改激活条件,比如从串口接到到一串固定的数据作为激活条件。
后续
其实我们在看参考手册时,还看到这么一句话:“For STM32F04x and STM32F09x devices, see also Empty check description.”也就是说,空片也是可以通过串口进行烧写的,我们后续继续讨论。
对应的代码:STM32F09x不使用BOOT脚实现System Bootloader升级代码
更多实战经验请看:【ST MCU实战经验汇总贴】
|