|
利用 USB DFU实现 IAP功能 $ f1 n% d8 d# i前言* X1 p# a7 _* Z; @# q4 m 伴随着固件升级需求的增加,STM32提供了灵活的升级方式。本文一步一步介绍如何利用USB DFU Class以及ST提供的DfuSe demo软件工具实现IAP(In Application Program)功能,但并不涉及到DFU class移植。 7 k( Y! z) C% Z" O 一 实现环境 开发板:STM32F746G-DISCO$ R1 h5 I5 _9 {! m2 J, m1 Y! K- o 开发库:STM32CubeF7 v1.3.0 集成开发环境:IAR v7.70.1.114860 _( k% ?: J$ k( d3 J :MDK-ARM Plus v5.20.0.0 (只需两者中一种)1 `' a9 {* e/ D9 _# m9 b 优化级别 : High (IAR) Level 3 (-O3) (MDK-ARM) DFU演示软件: Dfu file manager v3.0.5/ n5 |* n: }' z7 Z0 g DfuSeDemo v3.0.59 | }# t8 t1 x+ O2 e7 s. x9 y ( g6 i2 G. l' Y/ D: ? 实现过程在STM32F7系列上展开,但USB DFU实现的IAP功能并不只局限于STM32F7系列,可以通过用户手册判断所采用微控制器型号是否支持USB以及IAP功能。STM32Cube开发库为各系列STM32提供了齐全的USB DFU例程可供参考。 + u6 o7 }/ K3 ]& \ 二 IAP介绍3 w- a5 |3 U1 h6 c2 n k+ K7 ] IAP(In application program)主要为使用者提供了一种更加灵活的固件升级方式,可以根据应用需要定义何时、何种情况发生时进行固件升级。在介绍步骤前,需要对IAP原理有一定认识。结合下图(仅供参考,IAP实际应用方式更加灵活),IAP的应用中,用户程序与IAP驱动程序位于不同的存储区域。在应用过程中,利用IAP驱动程序将用户固件加载到固定位置,完成升级。更多关于IAP应用介绍请参考AN3965。 其中,IAP驱动程序首先烧录固化,并不会随着用户程序的升级而改变。用户固件升级完毕后,在IAP驱动程序引导下,跳转到用户固件对应Flash位置,执行用户程序。7 E9 }' U# A7 _8 N9 `- Y 8 G; t- S) T/ b4 w5 \5 l
- h. Q4 L: [ s$ A4 l9 r( I- o 三 实现步骤 # R" t0 J% s3 @' w. E( M( }$ x9 ^ 3.1 DFU工具安装$ e9 d% h) s5 {4 V9 g5 {0 w2 N 安装DFU demo工具DfuSe v3.0.5,主要提供了驱动、Dfu file manager 和 DfuSeDemo。关于DfuSe的详细内容(安装步骤、使用介绍)请参考UM0412。3 t8 G0 X* _. [% c) S- {4 }. [ 1 g9 N/ [& Y7 y1 m# D" ^ 3.2 IAP驱动固件生成与装载3 u* C J8 Q2 {5 L9 G: u 利用STM32CubeF7 v1.3.0开发库提供的USB DFU例程生成IAP驱动固件(文件夹路径: …\ STM32Cube_FW_F7_V1.3.0\Projects\STM32746G-Discovery\Applications\USB_Device\ DFU_Standalone)。1 o! z% K7 d; M2 E* C% S4 J 利用烧录工具烧录到开发板中。本例程实现重启后,如果板上User按键按下或者没有有效的用户应用程序,则进入USB DFU模式,等待升级;否则,进入用户应用。8 ? u9 ]: D' }6 q( c" H! A+ S 下面是摘取的部分例程。* ? h) k0 I! g0 t % w5 F8 N0 [ M6 ?$ q0 z
用户固件对应的首地址被定义在0x08008000。用户也可以自定义地址,需要注意如下几点:2 U) ~. h+ l( D/ G. o @" @ 1. 禁止定义在0x08008000地址前(STM32F7系列,0x0~0x0800FFFF属于Sector0,已经开辟为IAP驱动程序区域); p0 A; Q; `) Z" t8 L _- \ 2. 自定义地址所属Sector在升级时会全部擦除,即使定义地址并不位于对应Sector的首地址, _ D6 U" W) q 3. 自定义地址需要保持512-byte对齐 4. 自定义地址需要与用户固件对应的装载地址以及用户中断向量表地址保持一致" C6 \' F% o/ n 在实现跳转到用户程序的代码中,将用户中断向量表中第一个4字节指向的栈首地址分配给MSP。第二个4字节为复位中断向量,指向执行首地址。 在开发IAP驱动程序时,需要避免PC指针跳到用户程序区域。同时,充分考虑Stack & Heap大小,避免出现USB DFU正常识别,但不能正常工作情况,如下图所示。/ H# l) f+ z3 a0 i+ n; v: J 5 M- [8 K9 c w. m; d+ f7 V/ I
3.3 用户固件生成 本文采用STM32CubeF7 v1.3.0开发库中TIM_TimeBase例程作为用户程序(文件夹路径:STM32Cube_FW_F7_V1.3.0\Projects\STM32746G-Discovery\Examples\TIM\TIM_TimeBase)。2 ?" A& W# w* y1 I IAP升级所需用户固件,主要有两处需要变动: 1. 在链接工具中,程序装载地址8 B+ C8 _9 j$ U% v1 d) R 2. 中断向量表首地址 上述两种变动需要保持一致,并且与IAP中定义的用户区域首地址保持一致。" s \9 _7 Z6 T ^ 本IAP驱动程序中,用户固件装载地址相对于0x08000000偏移地址为0x8000。在MDK中,改动前后比较如下图所示。9 {2 C4 c1 Z- N/ B; H; K
在IAR中,更改步骤如下所示。2 \( e, ~; E7 _
修改完毕后,生成hex文件(STM32746G_DISCOVERY.hex)。, ~0 _/ M F* Q9 T' L8 R' P* x . \* s8 r( ~8 l# a, H. s7 Z" ` 3.4 用户固件转换与升级5 K/ P" e5 g* j1 r! q& v; f# S 打开Dfu file manager工具,点击OK,进入转换工具主界面。
按照下图步骤,首先载入生成的HEX文件(STM32746G_DISCOVERY.hex);然后在Target ID、 Target Name、 Device properties中自定义内容,这部分内容在DfuSe Demo工具中选择.dfu文件时会予以显示,并不影响烧录文件内容。最后,点击Generate完成HEX文件DFU文件转换。
" [$ `" v3 x( E" W2 k8 ` 为STM32F746G-DISCO板供电,通过USB线将板上USB_FS接口与电脑相连。由于ST Discovery板已经加载了IAP应用程序,并且没有有效的用户应用程序,因此在IAP应用程序中,直接进入USB DFU模式,以供电脑识别USB DFU器件。正常识别情况如左下图。$ Z1 A8 }2 m$ K2 V+ g9 @ 右下图情况是由于没有正确装载Driver导致,可以通过右击“DFU in FS Mode”选择更新驱动程序软件\浏览计算机以查找驱动程序软件(驱动文件位于DfuSe v3.0.5安装目录\ DfuSe v3.0.5\Bin\ Driver)。 / C6 |, U; x$ [
打开DfuSeDemo,结合下图步骤,点击’Choose’加载之前转换的.dfu文件;选择配置;点击’Update’完成擦除与下载;另外,可以通过点击’Verify’验证是否下载成功。更多关于DfuSe内容,请参考UM0412。' W* y& d. U3 B' I( g . i; Y" G6 X4 z; L
用户固件升级完成。重启后,正常进入用户应用。如果重启过程中,板上USER键按下,进入USB DFU模式,等待升级。, b+ S2 b0 X0 h9 P& c 8 h3 g8 U+ J& H/ S$ |, y; t 四 小结3 {, X2 M+ |' o! h7 n% M 介绍了利用USB DFU实现IAP过程,以及实现过程中注意事项。在DfuSe v3.0.5安装目录中包含了必要的文档,介绍如何使用DfuSe工具,以及如何开发基于STMicroelectronics DFU方案的上位机应用。 2 n5 T* T4 o1 G( ` 相关文档 AN4657 STM32 in-application programming (IAP) using the USART AN3965 使用 USART 实现STM32F40x/STM32F41x 的 IAP UM0412 Getting started with DfuSe USB device firmware upgrade STMicroelectronics extension 相关工具&链接 DfuSe_Demo http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stsw-stm32080.html?dl=537587854391172693#. `7 s' j" O5 ~9 ^* n: W STM32CubeF7 http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef7.html# E% L$ L [) d, t% Y+ {3 x ( ]+ b1 C4 g7 Q$ y0 m 文档下载地址:% I2 S! U/ p/ w+ S [' P1 m. b https://www.stmcu.org.cn/document/detail/index/id-217183 1 y: F+ I+ N; F% T. h5 D 实战经验汇总: https://www.stmcu.org.cn/module/forum/thread-576401-1-1.html9 p- I) q* L+ A# i% F9 e - c* a/ }7 v) H6 J; r |
最全USB HID开发资料,悉心整理一个月,亲自测试
【源码】STLINK-V3MINI 高速USB仿真器,成功改刷【高速CMSIS-DAP】
STM32 USB CDC 虚拟多串口
实战经验 | 选择USBX模块生成USB CDC ACM无PD的项目
STM32 USB HID键盘例程
刘氓兔的杂谈【001】-片上USB 高速PHY
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
在线直播|无需编写任何代码即可在STM32上实现USB-C Power Delivery
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
USB Audio设计与实现
微信公众号
手机版
在下在用STM32F103ZE实现USB DFU的时候出现以下疑惑:" n9 A" i8 U: ^+ z8 A# [
1、在USB设备标识符中指出有1个接口,而所有的接口描述符都是通过一个宏实现6 m$ s" C V. s
#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \9 v; p; K) I! h D) X6 r
0x00, /* bInterfaceNumber: Number of Interface */ \
(n), /* bAlternateSetting: Alternate setting */ \" ]+ a& |) W) ~9 t7 R
0x00, /* bNumEndpoints*/ \
0xFE, /* bInterfaceClass: Application Specific Class Code */ \
0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
0x02, /* nInterfaceProtocol: DFU mode protocol */ \1 d. c4 i5 k* F1 k S7 f+ E/ r0 ]4 j) S
USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \& R- v0 N' X# H& E3 \( B
但是在这个接口描述符中指出端点数为0,但是发现USB状态机里面用的都是端点4的状态,这里有点费解( `7 e) D. P4 ~/ ?1 I0 O; |9 V
2、在DFU上位机中有个“Leaves DFU mode”按键,用于退出DFU模式,但是总是在49%时出错,查阅资料发现网上有许多人出现此问题。测试发现,如果在点击“Leaves DFU mode”按键后,USB设备只要响应完返回状态这个请求后,把USB设备的USB接口从PC拔出,则上位机显示成功。
点评
你好,我的毕设课题就是跟这个相关的,可以麻烦你讲讲固件升级在客户中的应用情况吗?