STM32 IAP应用开发——通过内置DFU实现USB升级(方式1)



By
jonson
12 4 月 24
0
comment

什么是IAP?

IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到数据存储区,从而实现固件升级。

什么是BootLoader?

百度百科:在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

实际上,BootLoader不仅仅在操作系统上使用,在一些内存小,功能应用较为简单的单片机设备上面也可以通过BootLoader来完成固件升级。

什么是DFU?

DFU全称为Download Firmware Update,是ST官方推出的一个通过USB接口进行IAP升级的方案,同串口ISP一样,他们都集成在了芯片内部的Bootloader区段,可以通过配置boot引脚来启动。

不过STM32内置DFU的型号都比较新,像STM32F4系列是有的,但是像F0和F1系列则没有,不过没有关系,如果你用的型号没有内置DFU程序,也可以通过CubeMX来快速生成和移植一个DFU功能程序到你的Flash中来使用。

使用DFU的优缺点?

使用DFU的好处是不用自己制作Bootloader,因为这部分代码在STM32出厂之前就已经做好并且烧录进去了,而且不占用用户代码的Flash,另外,在PC端我们也不需要专门定制一个上位机,因为官方就有专门的升级Tool以及USB驱动。

缺点是要改变boot引脚的电平,才能启动Bootloader,这样的话在应用场景上就有比较大的限制了。

所以,要根据项目的实际需求去选择合适的方案。

我之前也有发过一些关于STM32远程升级的文章,实现的方式有很多种,感兴趣的同学可以去看一下。

STM32固件升级系列合集:https://blog.csdn.net/ShenZhen_zixian/article/details/129074047

1 硬件介绍

我这里测试用的是STM32F407。

注意:F0和F1系列是沒有內置DFU的。

用到的硬件接口如下:

接口 引脚 作用
USB PA11 PA12 (必要)通过USB连接PC端,用来传输固件以实现在线升级
BOOT BOOT0 BOOT1 (必要)通过改变boot电平来切换运行模式
串口 PA9 (非必要)通过CH340连接到PC端,打印固件版本号,方便查看升级是否成功
LED PF9 (非必要)方便查看代码是否跑起来了

BOOT引脚配置对应如下图:

请添加图片描述

1)主Flash

主Flash起始地址为0x08000000,它指的是STM32内置的Flash,通常我们烧录的代码就是存放在这个位置。

2)系统存储器

系统存储器起始地址为0x1FFF0000,这种模式启动的程序功能是由芯片厂家设置的,STM32在出厂时会这个区域内置一段BootLoader, 也就是我们常说的ISP程序, 这是一块ROM,出厂后无法修改。我们要使用的DFU就是放在这里。

3)嵌入式SRAM

嵌入式SRAM起始地址为0x20000000,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的 地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。

2 环境搭建

2.1 Keil uVsion

关于STM32以及Keil的环境这里就不具体介绍了,网上教程也很多,不懂的同学自行查阅资料。环境搭建好之后需要准备一个能够正常运行的代码,用来测试我们后面的固件升级。

2.2 STM32CubeProgrammer

这个工具是用来烧录代码的,可以通过ST-Link、UART和USB下载。其中USB下载就是我们今天要讲的DFU模式。

STM32CubeProgrammer官方下载地址:https://www.st.com/en/development-tools/stm32cubeprog.html

请添加图片描述

根据自己的操作系统下载对应的安装包,然后直接安装即可。

请添加图片描述

提示:默认地址C:Program FilesSTM32CubeSTM32CubeProgrammerbin,如果安装完找不到应用程序的话可以在这个路径找到。

2.3 zadig

zadig是用来安装一个USB驱动的,只有安装好这个驱动,后面的升级流程才能正常进行,不然识别不到STM32的USB DFU模式。

这里先下载好软件,后面我们用到再安装。

下载地址请自行查阅,或者在我上传的链接下载也行。

zadig:https://download.csdn.net/download/ShenZhen_zixian/87570348

注:本文测试的时候,用的是v2.7.7版本。

2.4 检查USB驱动

1、让STM32进入系统存储器启动模式

也就是配置BOOT0引脚拉高,BOOT1引脚拉低。

提示:BOOT引脚的状态要在MCU启动之前配置好才能进入对应的模式,可以先配置BOOT引脚再上电,也可以在配置好BOOT引脚之后复位MCU。

请添加图片描述

2、检查和安装USB驱动

把STM32的USB连接到PC端,然后打开设备管理器,查看USB设备的情况。可能会出现以下几种情况。

1)能看到下图这个STM32 BOOTLOADER设备,并且没有黄叹号,说明驱动已经是安装好了的,可以直接跳到后面第3点了。

提示:因为前面安装STM32CubeProgrammer时会提示安装驱动,如果安装了,这时USB驱动可能就已经装好了。

请添加图片描述

2)能看到下图这个STM32 BOOTLOADER设备,但是有黄叹号,说明驱动异常,需要用zadig重新安装。

在这里插入图片描述
打开前面下载好的zadig,点击Install WCID Driver安装即可。

请添加图片描述

等待安装完成。

请添加图片描述

安装完成后可以在zadig上看到设备,打开设备管理器,也能看到一个没有黄叹号的STM32 BOOTLOADER设备。

请添加图片描述

请添加图片描述

3)能看到下图这个STM Device in DFU Mode设备,但没有STM32 BOOTLOADER设备,需要用zadig重新安装。

在这里插入图片描述

先卸载掉STM Device in DFU Mode设备。然后重新插拔USB线,之后会看到一个带黄色感叹号的STM32 BOOTLOADER设备。此时再按照前面的第2步操作即可。

在这里插入图片描述

不管是哪种情况,如果前面的驱动安装没有问题,连接上电脑之后可以在设备管理器也能看到一个STM BOOTLOADER设备,而且是没有黄色感叹号的。这样驱动就是OK的了。

请添加图片描述

3、打开STM32CubeProgrammer

如果驱动和接线都没问题,那么在STM32CubeProgrammer可以看到检测到STM32设备。

提示:如果没有找到设备,请检查前面的步骤。

请添加图片描述

至此,环境部分就搭建完成了。

3 固件升级

1、连接USB

把STM32的USB接入到PC端。

在这里插入图片描述

在STM32CubeProgrammer上连接设备。此时能读取到芯片的Flash。

注意读取的地址和长度,STM32的地址都是以0x08000000开始的,读取的长度就无所谓了,看你自己的需要。

请添加图片描述

2、导入hex或bin文件

打开要升级的固件(hex或bin都可以)。

请添加图片描述

请添加图片描述

打开后能看到固件存储的数据。

请添加图片描述

3、下载固件

点击“Download”,下载固件到STM32.

请添加图片描述

4、重启设备

升级完成后将BOOT模式要改成主Flash模式(BOOT0引脚拉低),然后重新上电或复位,即可运行新版本的代码。

请添加图片描述

至此,整个升级流程就走完了。

结束语

好了,关于如何通过STM32内置DFU实现USB升级就讲到这里,这种方式虽然限制较多,但在某些应用场景是很方便的,比如SB键盘,不需要自己编写Bootloader和上位机就可以实现固件升级,而且官方的升级渠道还稳定。其他应用场景就再另说,合适的才是最好的。

如果你有什么问题或者有更好的方法,欢迎在评论区留言。

发表回复