我们在《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 时更新:当地址 0x08000000 读出的内容为 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。然后点击“Full chip 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.0ProjectsSTM32F091RC-NucleoDemonstrationsBinary 的示例代码文件 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。然后点击“Full chip 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 升级代码》,我们就可真正地完全使用串口来进行代码烧写了。
|