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

【实战经验】USB DFU IAP例程移植的两个话题

[复制链接]
zero99 发布时间:2017-4-5 17:53
USB DFU IAP 例程移植的两个话题

5 r/ x0 z4 v- A( {; R前言
0 z1 }/ c4 P/ S2 p在STM32 的系列产品中,很多型号都带有USB 接口,为使用USB 来进行代码升级提供了便利。这些型号中又有很大一部分可以通过内部System Memory 中的Bootloader 直接进行USB DFU 升级,具体哪些型号支持USB DFU,可参考应用笔记AN2606《STM32 微控制器系统存储器自举模式》。有些型号虽然有USB,但是System Memory 中的Bootloader 并没有支持USB DFU,比如STM32F102 / STM32F103、或者Bootloader V2.x 的STM32F2xxx、STM32F303,等等,或者用户希望通过不同的触发方式进入bootloader 来进行USB 下载,比如接收一串编制好的数据来触发。那么,就要使用USB DFUIAP 了。关于如何使用USB DFU IAP 的简要说明,可参考另一份文档《利用USB DFU 实现IAP 功能》。在这里,主要要谈的是在USB DFU IAP 例程进行移植时,需要注意的两个地方。5 a( {5 w. J3 L# s) [! ]3 c/ @
1 Q0 `3 d- |2 O

' r- [- q6 ?3 b1 j! f+ \* }问题一
4 Q0 w+ y+ q' j: r5 a1 Y某客户在其产品的设计中,使用了STM32L073RBT6。客户在开发过程中,使用STM32L0Cube 库中的STM32L073Z_EVAL的DFU_Standalone 进行代码移植,完成后在使用Dfuse Demo 软件烧写用户代码时发生了错误。
+ r, m/ z: {5 X4 P! \
/ D, v, s- ^, F/ T. N% @9 W调研
& E$ J* O1 Z* a& m$ I1.了解问题0 r* p0 _3 x  E' P9 X* v
客户在开发中使用了STM32L0Cube 库STM32Cube_FW_L0_V1.7.0,对里边的\Projects\STM32L073Z_EVAL\Applications\USB_Device\DFU_Standalone 例程进行修改,以应用于用户板。客户已经根据硬件上的区别,对LED 灯和按键的I/O 口配置做了相应的修改,并在main.h 中使能了USE_USB_CLKSOURCE_CRSHSI48,因为其使用STM32L073 内部的48MHz 振荡作为USB 时钟源。客户编译通过后,使用ST-Link 将其下载到STM32L073RBT6 中。然后断开ST-Link,使用USB 进行连接,PC 可以认到“STM Device in DFU Mode”。打开DfuseDemo 软件,也可发现已经识别到STM32L073 处于DFU Mode。
/ E1 _; R0 j" r- [7 A' o
11.jpg ! t2 J. ]& C( K4 r, a  k# Z( D) a
但是,当用户选择了“Verify after download”,并点击“Choose”按键选择用户代码.dfu 文件后,并点击“Upgrade”进行
- r3 x2 {4 J9 S0 _+ J  v7 F$ n3 q烧写,发现弹出了提示发生错误的对话框,如下:
# a/ s1 E$ h" w+ f7 h
12.jpg 9 L4 N# j1 l9 q' d

+ @$ S& Y: {: E4 U5 |2.问题分析
, s: u' Y) Z8 c' h8 L& Y% oSTM32L073Z_EVAL 开发板使用的芯片型号为STM32L073VZT6,其Flash 容量为192KB,地址从0x08000000 到0x0802FFFF。而客户所使用的STM32L073RBT6,其Flash 容量为128KB,地址从0x08000000 到0x0801FFFF。检查项目中的usbd_conf.h 文件中的代码,客户并未作任何修改,也就是说,以下两个定义没有根据实际的型号进行修改:0 t. f. `  [' X! U. t. b; U
13.png
, r: E& r& ]) s/ B) j% ^
! D9 w& T7 B- S- |  N7 ^! pUSBD_DFU_APP_DEFAULT_ADD 和USBD_DFU_APP_END_ADD 定义了用户代码空间的开始页和结束页。从这可以看出,用户代码是从0x08003C00 开始的,也就是第120 页,而结束于第1535 页。STM32L073VZT6 从第0 页到第1535 页共1536 页,每页128 Bytes。客户使用的是STM32L073RBT6,总共才1024 页。显然,这里对USBD_DFU_APP_END_ADD的定义并不对,需要修改为第1023 页的地址。
# z9 ^3 {" S& x# m) q8 f. L2 v
1 l$ U& g$ n, U' W2 u! F
* w6 j: X; \8 A8 M2 r$ J9 i3.问题解决
+ N" }: I5 Q: V. V% h将usbd_conf.h 中的USBD_DFU_APP_END_ADD 修改为第1023 页的地址:8 D! i8 d) S0 ]$ f- q$ A
14.png
, t2 c' D0 @  W! i& ]+ T6 H问题解决,USB DFU 可以下载代码了。可是别急,这样就已经修改好了吗?再来看第二个话题。; O+ f$ O1 U5 y- v5 \: b

/ F% M6 A: h( P: r( a; g  U, R( q问题二
1 j% h( Y" b5 j! W- l% c/ G在问题的解决过程中,有没有注意到Dfuse Demo 界面中显示“1536 sectors”?这明显不对,来看看怎么修改。' `$ i9 t3 N  \* g/ M' s/ p: K
调研/ G7 V( y4 A, R/ o+ [2 v1 N6 t( T2 A
1.了解问题2 Z4 c0 K7 J9 U. e7 K
在Dfuse Demo 界面中,双击“1536 sectors”,可以看到Internal Flash 的详细信息,如下:  w* K+ n1 a- p3 h8 K' h' L  s
15.jpg 1 c/ i( T/ |, @/ p, F

( v$ t2 q+ _5 `2.问题分析
/ K7 S1 E6 a  Y6 {* K从上图可以了解到,实际上这里所定义的Sector 的大小为128Bytes,也就是STM32L073 的Page,所以这里的Sector 定义与STM32L073 的参考手册定义的Sector 是不一样的,不要造成误解。在RM0367 中,每128Bytes 为1 个Page,每32 个Page 才是1 个Sector。所以不要误会就行了。在这个Mapping 窗口中,也可以看到地址0x08003C00 之前的空间为Readonly,也就是Bootloader 所处的空间为只读,以避免对这部分代码的重写。而后面的空间,也就是用户代码所处的空间为Read/Write/Erase。( _" u- ]: @5 f+ A. c/ W. y& \
这些信息是从哪里来的呢?其实它来自于usbd_dfu_flash.c 里边定义的描述符FLASH_DESC_STR,如下:
( \: I1 j& {$ ?; ]- r- x& R
16.jpg ' Z( }* L$ |5 J
来解释一下这个描述符的内容:' L! F- e9 p( ?% O& E0 c3 ]
0x08000000 为起始地址。“a”代表的是Read-only,“g”代表Read/Write/Erase。也就是说,“a”所指明的区域为Bootloader 的空间,“g”所指明的区别为用户代码空间。大小由前面的数字决定,乘号“*”前面的为Sector 的个数,后面的为Sector 的大小,这里的意思就是从0x08000000 开始,前面120 个Sector(每个Sector 为128 字节)为Read-only,后
" t4 \$ S$ F0 t0 k面1416 个Sector(每个Sector 为128 字节)为Read/Write/Erase。+ K( {5 V  Z6 C2 l2 V4 J9 g

8 B% [) M: J+ F( I+ l- g% ?
% W* o5 Y1 g7 o9 j举另外一个例子,在\Projects\STM32L053C8-Discovery\Applications\USB_Device\DFU_Standalone\Src 下的
8 y, e/ {" o; _. X: @% D" kusbd_dfu_flash.c 是这样定义的:
9 Y! S# p% M: T
17.png
! _) W" u9 @+ O9 c% ?' f0 f0 O它的意思就是前面28 个Sector(每个Sector 为1KB)为Read-only,后面36 个Sector(每个Sector 为1KB)为Read/Write/Erase。因为在这个例子中,用户代码起始地址为0x08007000。在Dfuse Demo 的界面中,你也将看到只有64个Sector,双击打开后能看到每个Sector 为1KB。/ M) F: h0 O% L, G
8 i3 G/ G8 v4 i. v4 p

; n6 ^" N( I/ d3 h/ S9 t搞明白这个事,就知道如何去修改这个描述符FLASH_DESC_STR,让它符合STM32L073RBT6 的大小了。( ]+ F+ X5 T# q0 T8 x

- D; U, c" u' z4 y& \- z* ^3.问题解决
! U7 {7 t/ O! t; F& W* V* QSTM32L073RBT6 有1024 页,每页128 字节,所以需要修改描述符FLASH_DESC_STR 定义如下:8 \9 n4 o( T" [# q
18.png 1 N0 b3 ^1 r+ d

( p8 j3 J& m8 h' i  `2 N1 O附加话题: L: L# Q) t" t- Q+ g+ @/ a2 b
如果用户代码空间的定义还是这样的:9 E! }' H( }( K+ l9 }
19.png ( q- |# W+ A4 b
但是描述符FLASH_DESC_STR 的定义修改为:
8 l; s3 J+ a. L$ A
20.png   m1 a6 ^3 _( L1 i3 J% a3 d" B& x1 T
那会发生什么情况呢?
" V" p9 X) Z" g, @% s- G" D将 Bootloader 程序编译后烧写到STM32L073 中,然后使用USB 接口进行连接,打开Dfuse Demo。首先,可以看到界面中显示的就是128 Sectors,双击打开,每个Secotor 大小为1KB。
7 o( H+ {- u3 q5 k" R5 B$ f# T
21.png
" C3 l5 v" x4 j5 @+ i1 Y; I

, J$ a- W# Z0 j* H1 L" }接下来,来烧写一个用户代码,从0x08003c00 地址开始的。在Verify 时,就会弹出错误的对话框:
2 u& {7 ~, _, ^+ k5 F# z# O6 ^ 22.png 4 k6 A& j- W5 a6 r! }4 r
验证在0x08003C00 的地址就已经发生了错误:烧录文件该地址的数据为0x58,但是读回来的是0x00。这就是因为我们把描述符FLASH_DESC_STR 错误地定义成了前面28KB 为Read-only,也就是从0x08007000 开始才是可读/可写/可擦除的。所以,在0x08007000 之前的空间是不可擦除和写入的,也就导致了这样的情况。这个附加话题也只是为了强调这个描述符FLASH_DESC_STR 的重要性。
4 z% @/ c' W7 `# B$ ?& e5 s& J# ~# d2 v0 ?
结论
3 a' c, \! k, f; L0 @使用USB DFU IAP 参考例程进行移植的时候,Bootloader 的空间以及用户代码的空间的定义全部都需要根据具体的STM32型号进行修改。

1 e: U: g! M+ P; A5 P, b; B& ]8 r& w* k0 v
4 g% ]5 Q) [6 E. _/ }
  I5 [; O9 C: z4 B! [: o
USB DFU IAP例程移植的两个话题.pdf (272.47 KB, 下载次数: 99)
赞 1 收藏 3 评论2 发布时间:2017-4-5 17:53

举报

2个回答
斜阳 回答时间:2017-4-5 21:54:34
好文章
dfr3602 回答时间:2020-12-24 12:52:22
目前STM32部分MCU已经集成USB驱动,方便。

所属标签

相似技术帖

官网相关资源

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