[应用相关]

USB DFU IAP 例程移植的两个话题

[复制链接]
1028|26
手机看帖
扫描二维码
随时随地手机跟帖
我只会加减乘除|  楼主 | 2021-11-10 14:18 | 显示全部楼层 |阅读模式
前言前言
在 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 DFU
IAP 了。关于如何使用 USB DFU IAP 的简要说明,可参考另一份文档《利用 USB DFU 实现 IAP 功能》。在这里,主要要谈
的是在 USB DFU IAP 例程进行移植时,需要注意的两个地方。  

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:19 | 显示全部楼层
问题问题一
某客户在其产品的设计中,使用了 STM32L073RBT6。客户在开发过程中,使用 STM32L0Cube 库中的 STM32L073Z_EVAL
的 DFU_Standalone 进行代码移植,完成后在使用 Dfuse Demo 软件烧写用户代码时发生了错误。

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:20 | 显示全部楼层
调研调研
1.1.了解问题
客户在开发中使用了 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”。打开 Dfuse
Demo 软件,也可发现已经识别到 STM32L073 处于 DFU Mode。
19342618b64a1df545.png
但是,当用户选择了“ Verify after download”,并点击“ Choose”按键选择用户代码.dfu 文件后,并点击“Upgrade”进行
烧写,发现弹出了提示发生错误的对话框,如下:
95034618b64b3cd865.png

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:21 | 显示全部楼层
2.2.问题分析
STM32L073Z_EVAL 开发板使用的芯片型号为 STM32L073VZT6,其 Flash 容量为 192KB,地址从 0x08000000 到
0x0802FFFF。而客户所使用的 STM32L073RBT6,其 Flash 容量为 128KB,地址从 0x08000000 到 0x0801FFFF。检查项
目中的 usbd_conf.h 文件中的代码,客户并未作任何修改,也就是说,以下两个定义没有根据实际的型号进行修改:  

#define USBD_DFU_APP_DEFAULT_ADD 0x08003C00 /* Start user code address:
ADDR_FLASH_PAGE_120 */
#define USBD_DFU_APP_END_ADD 0x0802FF80 /* Start address of latest
flash page: ADDR_FLASH_PAGE_1535 */
USBD_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 页的地址。


使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:22 | 显示全部楼层
3.3.问题解决
将 usbd_conf.h 中的 USBD_DFU_APP_END_ADD 修改为第 1023 页的地址:  

#define USBD_DFU_APP_END_ADD 0x0801FF80 /* Start address of latest
flash page: ADDR_FLASH_PAGE_1023 */
问题解决, USB DFU 可以下载代码了。可是别急,这样就已经修改好了吗?再来看第二个话题。


使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:23 | 显示全部楼层
问题二
在问题的解决过程中,有没有注意到 Dfuse Demo 界面中显示“ 1536 sectors”?这明显不对,来看看怎么修改。

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:23 | 显示全部楼层
调研调研
1.1.了解问题
在 Dfuse Demo 界面中,双击“ 1536 sectors”,可以看到 Internal Flash 的详细信息,如下:
16482618b655cee850.png

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:24 | 显示全部楼层
2.2.问题分析
从上图可以了解到,实际上这里所定义的 Sector 的大小为 128Bytes,也就是 STM32L073 的 Page,所以这里的 Sector 定义
与 STM32L073 的参考手册定义的 Sector 是不一样的,不要造成误解。在 RM0367 中,每 128Bytes 为 1 个 Page,每 32 个
Page 才是 1 个 Sector。所以不要误会就行了。在这个 Mapping 窗口中,也可以看到地址 0x08003C00 之前的空间为 Readonly,也就是 Bootloader 所处的空间为只读,以避免对这部分代码的重写。而后面的空间,也就是用户代码所处的空间为
Read/Write/Erase。
这些信息是从哪里来的呢?其实它来自于 usbd_dfu_flash.c 里边定义的描述符 FLASH_DESC_STR,如下:  

#define FLASH_DESC_STR "[url=home.php?mod=space&uid=2283616]@internal[/url] Flash /0x08000000/120*128 a,1416*128 g"
来解释一下这个描述符的内容:
0x08000000 为起始地址。“a”代表的是 Read-only,“ g”代表 Read/Write/Erase。也就是说,“ a”所指明的区域为
Bootloader 的空间,“ g”所指明的区别为用户代码空间。大小由前面的数字决定,乘号“*”前面的为 Sector 的个数,后面
的为 Sector 的大小,这里的意思就是从 0x08000000 开始,前面 120 个 Sector(每个 Sector 为 128 字节)为 Read-only,后
面 1416 个 Sector(每个 Sector 为 128 字节)为 Read/Write/Erase。
举另外一个例子,在\Projects\STM32L053C8-Discovery\Applications\USB_Device\DFU_Standalone\Src 下的
usbd_dfu_flash.c 是这样定义的:
#define FLASH_DESC_STR "@Internal Flash /0x08000000/28*01Ka,36*01Kg"
它的意思就是前面 28 个 Sector(每个 Sector 为 1KB)为 Read-only,后面 36 个 Sector(每个 Sector 为 1KB)为
Read/Write/Erase。因为在这个例子中,用户代码起始地址为 0x08007000。在 Dfuse Demo 的界面中,你也将看到只有 64
个 Sector,双击打开后能看到每个 Sector 为 1KB。
搞明白这个事,就知道如何去修改这个描述符 FLASH_DESC_STR,让它符合 STM32L073RBT6 的大小了。

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:25 | 显示全部楼层
3.3.问题解决
STM32L073RBT6 有 1024 页,每页 128 字节,所以需要修改描述符 FLASH_DESC_STR 定义如下:
#define FLASH_DESC_STR "@Internal Flash /0x08000000/120*128Ba,904*128Bg"




使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:29 | 显示全部楼层
附加附加话题
如果用户代码空间的定义还是这样的:  

#define USBD_DFU_APP_DEFAULT_ADD 0x08003C00 /* Start user code address:
ADDR_FLASH_PAGE_120 */
#define USBD_DFU_APP_END_ADD 0x0801FF80 /* Start address of latest
flash page: ADDR_FLASH_PAGE_1023 */
但是描述符 FLASH_DESC_STR 的定义修改为:


#define FLASH_DESC_STR "@Internal Flash /0x08000000/28*01Ka,100*01Kg"
那会发生什么情况呢?
将 Bootloader 程序编译后烧写到 STM32L073 中,然后使用 USB 接口进行连接,打开 Dfuse Demo。首先,可以看到界面中
显示的就是 128 Sectors,双击打开,每个 Secotor 大小为 1KB。
66870618b66a55976e.png

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:30 | 显示全部楼层
接下来,来烧写一个用户代码,从 0x08003c00 地址开始的。在 Verify 时,就会弹出错误的对话框:
47668618b66c19d049.png
验证在 0x08003C00 的地址就已经发生了错误:烧录文件该地址的数据为 0x58,但是读回来的是 0x00。这就是因为我们把
描述符 FLASH_DESC_STR 错误地定义成了前面 28KB 为 Read-only,也就是从 0x08007000 开始才是可读/可写/可擦除的。
所以,在 0x08007000 之前的空间是不可擦除和写入的,也就导致了这样的情况。
这个附加话题也只是为了强调这个描述符 FLASH_DESC_STR 的重要性。

使用特权

评论回复
我只会加减乘除|  楼主 | 2021-11-10 14:31 | 显示全部楼层
结论
使用 USB DFU IAP 参考例程进行移植的时候, Bootloader 的空间以及用户代码的空间的定义全部都需要根据具体的 STM32
型号进行修改。

使用特权

评论回复
晓伍| | 2021-12-6 16:17 | 显示全部楼层
都是热门话题啊

使用特权

评论回复
八层楼| | 2021-12-6 16:17 | 显示全部楼层
利用 USB DFU 实现 IAP   这种方式应用的广泛吗

使用特权

评论回复
观海| | 2021-12-6 16:19 | 显示全部楼层
大部分都是两种usb接口吧

使用特权

评论回复
tpgf| | 2021-12-6 16:20 | 显示全部楼层
可以从其他地址开始吗

使用特权

评论回复
guanjiaer| | 2021-12-6 16:23 | 显示全部楼层
也就是需要对地址非常了解了

使用特权

评论回复
heimaojingzhang| | 2021-12-6 16:24 | 显示全部楼层
会不会数据溢出呢

使用特权

评论回复
bartonalfred| | 2022-12-5 22:13 | 显示全部楼层
所有STM32系列芯片都自带ISP功能

使用特权

评论回复
MessageRing| | 2022-12-6 13:38 | 显示全部楼层
Bootloader 的空间以及用户代码的空间的定义全部都需要根据具体的 STM32
型号进行修改

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

159

帖子

0

粉丝