本帖最后由 香水城 于 2017-8-16 15:01 编辑
STM32F091空片使用System Bootloader下载代码 前言
我们在《STM32F09x 不使用BOOT 脚实现System Bootloader 升级代码》中实现了通过修改Option Bytes 来达到控制BOOT0 和BOOT1,在不需要外部BOOT 脚的情况下实现了使用System Bootloader 进行代码升级的功能。可是,这个功能必须在程序中预先烧写了功能程序后,才能不断地进行升级。也就是说,在第一次空片烧写时,必须使用SWD 进行烧写的。那有没有可能在空片烧写时,就可以直接使用System Bootloader 进行烧写呢?这样我们就可以完全使用串口进行烧写和升级了。现在,我们来探讨这个问题。
问题
在使用STM32F091RCT6 时,能否进行对空片的串口烧写,结合《STM32F09x 不使用BOOT 脚实现System Bootloader 升级代码》实现完全使用串口进行烧写?
调研
1.认识一下STMF09x 和STM32F04x 在Boot Configuration 中的新特性
打开参考手册RM0091,翻到Boot Configuration 那一节,我们可以看到Table 3 中对Boot Mode 进行了描述,如下:
从表格中,在《STM32F09x 不使用BOOT 脚实现System Bootloader 升级代码》一文中我们只提到了第1 条注释:
“Grey options are available on STM32F04x and STM32F09x devices only.”
现在,我们再来看一下第2 条注释:
“For STM32F04x and STM32F09x devices, see also Empty check description.”
那我们再来看一下Empty check 的描述:
首先,我们看到,“Empty Check”是只有STM32F04x 和STM32F09x 才有的功能,内部有一个查空标志,可用于使用Bootloader 对未编程过的芯片进行简单编程。这个标志位在BOOT0 脚被定义到从Main Flash memory 启动的时候使用。当这个标志位被置“1”的时候,此芯片被认为是空的,系统将从System memory 中启动Bootloader,以允许用户进行代码下载,即使现在BOOT0 脚定义的是从Main Flash memory 启动。此标志位只在载入Option bytes 时更新:当地址0x0800
0000 读出的内容为0xFFFF FFFF 时,此标志位置“1”,否则为“0”。这意味着当烧写完一个空片后需要在系统复位后执行代码的话,是必须要重新上电或者在FLASH_CR 寄存器中置位OBL_LAUNCH。
也就是说,当我们把BOOT0 设置为0,设置为从Main Flash memory 中启动时,当上电时或者置位OBL_LAUNCH 启动一
个带载入新的Option bytes 的复位后。当Option bytes 载入的时候,STM32F04x/STM32F09x 会读取读取0x0800 0000 的内容,如果其值为0xFFFF FFFF,认为此芯片为空片,直接进入System Memory 中,使用Bootloader 启动;如果其值不是0xFFFF FFFF,则认为此芯片不是空片,直接从用户代码启动。
2.实验验证
实验使用工具:PC 一台,NUCLEO-F091RC 一块,USB 线1 条(用来连接NUCLEO 板与PC)
实验使用软件:STM32 ST-LINK Utility,Flash Loader Demonstrator
实验使用软件库:STM32Cube_FW_F0_V1.2.0
我们先来看第一个实验:
· 实验1:空片测试
1) 使用USB 线连接PC 与NUCLEO-F091RC
2) 打开STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接STM32F091。然后点击“Fullchip erase”按钮对Main Flash Memory 进行擦除。结果如图所示:
3) 我们再点击菜单“Target→Option Bytes”检查一下Option Bytes 的配置确实是初始值的状态。如下图:
4) 若是确认Option Bytes 是初始值,直接点“Cancel”退出对话框;若是Option Bytes 为非初始值,修改为初始值后点“Apply”完成Option Bytes 的更新并退出对话框。
5) 回到STM32 ST-LINK Utility,点击“Disconnect”按钮断开连接。
6) 断开USB 连接线,并重新连接。为STM32F091 重新上电。
7) 打开Flash Loader Demonstrator,选择正确的配置,比如下图:
NUCLEO 板上的ST-LINK 自带虚拟串口,而且已经连接到STM32F091 芯片上。此时虚拟串口对应的是COM16,所以选择COM16。
8) 点击“Next”测试连接,并继续往下测试烧写。
9) 测试结果:成功!
10) 到此,我们证明空片是可以直接使用Flash Loader Demonstrator 进行串口烧写的。但是我们再来探讨一些其他
情况。
· 实验2:测试0x0800 0000 地址的值为0xFFFF FFFF 的情况。
按参考手册RM0091 的描述,只要0x0800 0000 地址的值为0xFFFF FFFF 就可以进入System bootloader 了,即使BOOT 配置为Main Flash memory 启动。所以我们再来做一个实验:
1) 使用USB 线连接PC 与NUCLEO-F091RC
2) 打开STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接STM32F091。并点击“Open file”按钮,打开位于\ STM32Cube_FW_F0_V1.2.0\Projects\STM32F091RC-Nucleo\Demonstrations\Binary 的示例代码文件STM32CubeF0_Demo_STM32F091RC-Nucleo.hex。如图:
3) 点击“Program verify”按钮进行烧写。
4) 点击“Disconnect”按钮断开连接。
5) 断开USB 连接线,并重新连接。为STM32F091 重新上电。
6) 打开Flash Loader Demonstrator,点击“Next”,就会弹出下图所示的警告,证明无法连接。失败!
7) 切回STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接STM32F091。在“Device Memory @ 0x08000000:”页面中直接将0x0800 0000 地址中的数值修改为0xFFFF FFFF,这时软件会自动更新代码,将修改过的代码烧写到STM32F091 中,如下图:
8) 点击“Disconnect”按钮断开连接。
9) 断开USB 连接线,并重新连接。为STM32F091 重新上电。
10) 打开Flash Loader Demonstrator,点击“Next”测试连接,并继续往下测试烧写。
11) 测试结果:成功!
12) 到此,我们证明确实在Main Flash memory 中只要0x0800 0000 地址中的数值是0xFFFF FFFF 就可以直接使
用Flash Loader Demonstrator 进行串口烧写的。其他地址的数值并没有关系。那么,是不是只要这个条件就能
保证可以串口烧写呢?我们再来看下一个实验。
· 实验3:Option Bytes 测试
1) 使用USB 线连接PC 与NUCLEO-F091RC
2) 打开STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接STM32F091。然后点击“Fullchip erase”按钮对Main Flash Memory 进行擦除。结果如图所示:
3) 我们再点击菜单“Target→Option Bytes”,将Option Bytes 中的nBOOT0_SW_Cfg 位(也就是BOOT_SEL)
的打勾去掉。如下图:
4) 点击“Apply”完成Option Bytes 的烧写并退出对话框。
5) 回到STM32 ST-LINK Utility,点击“Disconnect”按钮断开连接。
6) 断开USB 连接线,并重新连接。为STM32F091 重新上电。
7) 打开Flash Loader Demonstrator,点击“Next”,又见到弹出下图所示的警告,证明无法连接。失败!
8) 那么,这是否证明如果Option Bytes 的值不是初始值的话,Empty Check 的功能将失效?同样的过程,我们再来试另外一个配置:
在这个配置中,我们将nBOOT0_SW_Cfg 位改回来“打勾”,再将其他打勾的项都取消掉。
9) 点击“Apply”完成Option Bytes 的烧写并退出对话框。
10) 回到STM32 ST-LINK Utility,点击“Disconnect”按钮断开连接。
11) 断开USB 连接线,并重新连接。为STM32F091 重新上电。
12) 打开Flash Loader Demonstrator,点击“Next”测试连接,并继续往下测试烧写。
13) 测试结果:成功!
14) 到此,我们证明Empty Check 是会对Option Bytes 中的BOOT_SEL 位进行检测的。只要BOOT_SEL 的值为“0”,而不是“1”,Empty Check 就认为这不是一个空片,不会跳往System Memory 去执行Bootloader。
结论
关于Empty Check 的断定条件,不仅仅是RM0091 所描述的检查Main Flash memory 中地址0x0800 0000 的值是否为0xFFFF FFFF,还检查了Option Bytes 中BOOT_SEL 位的值是否为“1”。只有在Main Flash memory 中地址0x08000000 的值为0xFFFF FFFF,且Option Bytes 中BOOT_SEL 位的值为“1”的情况下,才会跳往System Memory 去执行Bootloader。
到此,结合上一篇应用文档《STM32F09x 不使用BOOT 脚实现System Bootloader 升级代码》,我们就可真正地完全使用串口来进行代码烧写了
对应的PDF: STM32F091空片使用System Bootloader下载代码
更多实战经验请看:【ST MCU实战经验汇总贴】
|