你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F091 空片使用 System Bootloader下载代码

[复制链接]
STMCU小助手 发布时间:2022-2-18 21:54
前言+ w( C, J$ x- h$ P: F
我们在《STM32F09x 不使用 BOOT 脚实现 System Bootloader 升级代码》中实现了通过修改 Option Bytes 来达到控制BOOT0 和 BOOT1,在不需要外部 BOOT 脚的情况下实现了使用 System Bootloader 进行代码升级的功能。可是,这个功能必须在程序中预先烧写了功能程序后,才能不断地进行升级。也就是说,在第一次空片烧写时,必须使用 SWD 进行烧写的。那有没有可能在空片烧写时,就可以直接使用 System Bootloader 进行烧写呢?这样我们就可以完全使用串口进行烧写和升级了。现在,我们来探讨这个问题。
- }, o' K5 A% ?6 o! \  R- \3 c% {! e
, a9 N" K1 c3 j* e' ?% X% I& q问题
2 V5 S3 ]5 r% B9 r7 d在使用 STM32F091RCT6 时,能否进行对空片的串口烧写,结合《STM32F09x 不使用 BOOT 脚实现 System Bootloader 升级代码》实现完全使用串口进行烧写?
8 e8 \) [2 @+ [, X/ G. T% j4 B& Y1 d6 u6 I& a, N; r
调研
7 y) y5 x/ o' X1.认识一下 STMF09x 和 STM32F04x 在 Boot Configuration 中的新特性
; q$ _6 F4 e2 z* ~打开参考手册 RM0091,翻到 Boot Configuration 那一节,我们可以看到 Table 3 中对 Boot Mode 进行了描述,如下:. o4 E; l/ v, _# l

1 f' z3 v: }2 W" m _Y[[C}B%@H$JOTYH(3JW@)E.png / H$ U3 M* ]8 I' D* i- F" m

+ j+ z0 U7 G  N( {4 S1 O从表格中,在《STM32F09x 不使用 BOOT 脚实现 System Bootloader 升级代码》一文中我们只提到了第 1 条注释:# k: w. j% q5 n5 A5 E$ ^' Q
“Grey options are available on STM32F04x and STM32F09x devices only.”
6 v8 K6 p, t( D+ V% @4 I) m现在,我们再来看一下第 2 条注释:( ^8 O1 Z5 w: J8 n- p. `& i
“For STM32F04x and STM32F09x devices, see also Empty check description.”- o; Z; o/ b& D4 e
那我们再来看一下 Empty check 的描述:4 o3 F+ @/ Z# R2 w
6 K6 q6 k  @/ ^5 l" O
U}~XRWBIPO39K3{Y%`SUH_H.png ! y/ _7 L% u. C2 [% s

+ S" x* P9 Q( }' _8 a! t首先,我们看到,“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。  w. k2 j0 o' J; t; j2 `
也就是说,当我们把 BOOT0 设置为 0,设置为从 Main Flash memory 中启动时,当上电时或者置位 OBL_LAUNCH 启动一个带载入新的 Option bytes 的复位后。当 Option bytes 载入的时候,STM32F04x/STM32F09x 会读取读取 0x0800 0000 的内- m$ {9 i: P- p4 H
容,如果其值为 0xFFFF FFFF,认为此芯片为空片,直接进入 System Memory 中,使用 Bootloader 启动;如果其值不是
8 ~6 [3 Y- N1 Y) E% ^0xFFFF FFFF,则认为此芯片不是空片,直接从用户代码启动。: U) V& ?" C1 o% ]. D* |
$ M, }8 K  ~# t5 T" a
2.实验验证
% W$ w# l& i, ]0 \) w/ B% T# r+ t实验使用工具:PC 一台,NUCLEO-F091RC 一块,USB 线 1 条(用来连接 NUCLEO 板与 PC)
. Q8 s( O9 h" e实验使用软件:STM32 ST-LINK Utility,Flash Loader Demonstrator
( |' h) K- |2 [) b8 K) m实验使用软件库:STM32Cube_FW_F0_V1.2.0
6 _5 I, E) f3 b( y4 q" P我们先来看第一个实验:0 `# y6 x& m0 o* `; \+ x: p
• 实验 1:空片测试2 G; O. j/ E: ?2 b1 D' h. q
1) 使用 USB 线连接 PC 与 NUCLEO-F091RC
: e6 f6 ]- v+ Y& m% V2) 打开 STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接 STM32F091。然后点击“Full chip erase”按钮对 Main Flash Memory 进行擦除。结果如图所示:
: L1 i& w" p! O" ]) J5 S( M4 V3 {# x: Q$ U+ O' M: Y7 D
_AWQ4V~3VEAJJT@TMAQ5XPR.png
! \0 S( d5 B& i# Z+ S
9 R2 x" j8 a  e3) 我们再点击菜单“Target→Option Bytes”检查一下 Option Bytes 的配置确实是初始值的状态。如下图:& h& s5 V. D1 |0 A# K7 E. ~5 x4 I
3 x9 c* G5 S+ D6 T) P) W: n9 q5 e/ ^
V~SU8@9STMSEK([U]A{1COX.png   V7 a( k0 P, m# u, _) @
/ O' Q( d0 \- E! K
4) 若是确认 Option Bytes 是初始值,直接点“Cancel”退出对话框;若是 Option Bytes 为非初始值,修改为初始值后点“Apply”完成 Option Bytes 的更新并退出对话框。
# ]3 S: i9 N) x+ J5) 回到 STM32 ST-LINK Utility,点击“Disconnect”按钮断开连接。/ ~! p! U7 H7 _- u1 y
6) 断开 USB 连接线,并重新连接。为 STM32F091 重新上电。
( m4 Q0 D$ I6 B7 P9 q4 x7) 打开 Flash Loader Demonstrator,选择正确的配置,比如下图:" N# u1 }. C/ f8 r' `( q
, H6 e4 l' J5 d9 i
A3([{_DUQSJ4(6(XXBHRWBO.png
; y& h3 ~! p$ O$ {% T
; L& B' K% I/ S/ q1 j   NUCLEO 板上的 ST-LINK 自带虚拟串口,而且已经连接到 STM32F091 芯片上。此时虚拟串口对应的是COM16,所以选择 COM16。1 c! g: L# `- W  I
8) 点击“Next”测试连接,并继续往下测试烧写。. `7 J8 Z& m% U" g/ Y
9) 测试结果:成功!' A, B# @! C) C, D# m; L
10) 到此,我们证明空片是可以直接使用 Flash Loader Demonstrator 进行串口烧写的。但是我们再来探讨一些其他情况。
/ r: H3 w( d! P: j    • 实验 2:测试 0x0800 0000 地址的值为 0xFFFF FFFF 的情况。  p) G* M3 X" n" ^8 w
    按参考手册 RM0091 的描述,只要 0x0800 0000 地址的值为 0xFFFF FFFF 就可以进入 System bootloader 了,即使BOOT 配置为 Main Flash memory 启动。所以我们再来做一个实验:7 [$ v0 H8 v5 B) O' L5 y
1) 使用 USB 线连接 PC 与 NUCLEO-F091RC7 f6 r6 `5 w8 M5 k; I3 C
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。如图:
4 D' n/ t3 o. _, V3 H% j3 Q( T" f5 e, Y7 [0 [( u- e
FZS~_SJ8Q]5GKEJ}}@@K$HF.png
9 K+ x1 M! \$ H) v1 Q& j; s5 O5 p7 V0 p1 X2 f+ u
3) 点击“Program verify”按钮进行烧写。
9 I8 F  D7 ~- S4) 点击“Disconnect”按钮断开连接。+ k8 @& D% {) l
5) 断开 USB 连接线,并重新连接。为 STM32F091 重新上电。% H: }+ U5 Z, A# ]
6) 打开 Flash Loader Demonstrator,点击“Next”,就会弹出下图所示的警告,证明无法连接。失败!; d( F2 h6 o+ a8 m$ c, h

4 X5 f' v9 {" Q  j9 P7 ]$ A $B@OFTC71P0$K[UAOFW]5R4.png * ~' S2 C( F4 v& a9 K+ d, f

: f2 A1 J7 ]" b2 j7) 切回 STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接 STM32F091。在“DeviceMemory @ 0x08000000:”页面中直接将 0x0800 0000 地址中的数值修改为 0xFFFF FFFF,这时软件会自动更新代码,将修改过的代码烧写到 STM32F091 中,如下图:
( n" D$ @9 ^# |, r
+ P. q* u' L) a. H" V- x- w8 |+ G. U. T% A, p: E1 T" w' j7 M1 v
MSM09WYLOS0%~8H7ZK~9VIO.png
7 |. W% C( G# \5 ]4 a& G! Q+ t. {; {1 o$ Y! e- _8 U
8) 点击“Disconnect”按钮断开连接。
/ X% A2 i* a- P! a9) 断开 USB 连接线,并重新连接。为 STM32F091 重新上电。; G+ |8 H8 T0 f4 j' r/ f  y
10) 打开 Flash Loader Demonstrator,点击“Next”测试连接,并继续往下测试烧写。
" Z' U' i! h& z7 g! S' \11) 测试结果:成功!
: ^8 z0 f! z+ W& F. o12) 到此,我们证明确实在 Main Flash memory 中只要 0x0800 0000 地址中的数值是 0xFFFF FFFF 就可以直接使用 Flash Loader Demonstrator 进行串口烧写的。其他地址的数值并没有关系。那么,是不是只要这个条件就能保证可以串口烧写呢?我们再来看下一个实验。
- }( O% l4 F9 k* V! m, |' ]    • 实验 3:Option Bytes 测试) J1 Z' O7 q; G) S$ B7 v$ B9 u  L
1) 使用 USB 线连接 PC 与 NUCLEO-F091RC( Z. d- d' t" Y( V7 A" }0 r* J
2) 打开 STM32 ST-LINK Utility 软件,点击“Connect to the target”按钮,连接 STM32F091。然后点击“Full chip erase”按钮对 Main Flash Memory 进行擦除。结果如图所示:0 F' y+ r( d; C" n
4 e' Q1 f$ H8 {
7`7%I((BLIZ_8QFK_1V_RKP.png
4 ]% x2 N6 `: K7 o( [5 w4 w- r3 [3 z# |) v
3) 我们再点击菜单“Target→Option Bytes”,将 Option Bytes 中的 nBOOT0_SW_Cfg 位(也就是 BOOT_SEL)的打勾去掉。如下图:
5 _; [, X1 Z+ {
  w+ E7 p5 e1 d/ |$ k )M(9V5[JV@NUL87EY]OK@HN.png
; Z$ _' k9 S, Y' a+ s& {, B0 [1 J/ n
4) 点击 “Apply”完成 Option Bytes 的烧写并退出对话框。+ m+ `! v( `, o# B
5) 回到 STM32 ST-LINK Utility,点击“Disconnect”按钮断开连接。
1 s1 q$ L+ [8 ]2 w+ H5 P* @6) 断开 USB 连接线,并重新连接。为 STM32F091 重新上电。
; A# D# I5 ]" b3 k; J0 d7) 打开 Flash Loader Demonstrator,点击“Next”,又见到弹出下图所示的警告,证明无法连接。失败!" r) W. ~2 _* v1 P: }& ?: |
/ D( X8 z( ^7 Y3 U. O# [+ G* O
JSDK3~3RQ)7[8BL[V[N[R13.png
6 L( _) E- }+ a3 l
) F0 V  k, d4 G/ e0 z9 R  ^0 v8) 那么,这是否证明如果 Option Bytes 的值不是初始值的话,Empty Check 的功能将失效?同样的过程,我们再来试另外一个配置:
, H9 F3 w2 Z3 F9 t
3 A! j2 e) t5 D$ D 8HASFV43FL@4`]X0XEQE(VT.png
# D- V& H+ D( R2 l+ i8 ]: a) n5 f8 K! d
    在这个配置中,我们将 nBOOT0_SW_Cfg 位改回来“打勾”,再将其他打勾的项都取消掉。
7 [& k0 E% Q& V( ], O  G- b! o9) 点击 “Apply”完成 Option Bytes 的烧写并退出对话框。
  Z) j0 {0 p  ]10) 回到 STM32 ST-LINK Utility,点击“Disconnect”按钮断开连接。0 _5 s" u- v( p6 M# e# Z
11) 断开 USB 连接线,并重新连接。为 STM32F091 重新上电。5 G- r  t8 S/ G+ G! _
12) 打开 Flash Loader Demonstrator,点击“Next”测试连接,并继续往下测试烧写。
- [+ |& v2 \% Q/ X" c0 R13) 测试结果:成功!7 p) z1 B1 Z/ O! Q& n. Q
14) 到此,我们证明 Empty Check 是会对 Option Bytes 中的 BOOT_SEL 位进行检测的。只要 BOOT_SEL 的值为“0”,而不是“1”,Empty Check 就认为这不是一个空片,不会跳往 System Memory 去执行 Bootloader。
# M2 A: Y/ X: t: ?" p) [
# A: q3 R$ [5 W9 r6 Y- x    结论+ q( G4 J, u# j5 m8 t: O* L
    关于 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。5 P; A' n# O  ?0 ^' k
    到此,结合上一篇应用文档《STM32F09x 不使用 BOOT 脚实现 System Bootloader 升级代码》,我们就可真正地完全使用串口来进行代码烧写了。7 A, k$ {% M5 }* c# v( ~8 N

' ?8 C* P5 u- |! y7 R. a: C
赞 收藏 评论0 发布时间:2022-2-18 21:54

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版