简单几步,搞定STM32 DFU固件升级

B站影视 韩国电影 2025-10-24 00:08 1

摘要:开发阶段我们往往是通过ST-Link或串口对STM32固件进行更新,但设备装好以后,如果再用这两种方式就不方便了。因为需要打开机壳才能连接ST-Link或插拔跳线帽改变BOOT。

开发阶段我们往往是通过ST-Link或串口对STM32固件进行更新,但设备装好以后,如果再用这两种方式就不方便了。因为需要打开机壳才能连接ST-Link或插拔跳线帽改变BOOT。

如果所用的MCU支持USB,可以用它的DFU(Device Firmware Update)模式在不用拆机的情况下通过USB口进行固件升级。当然,这需要在驱动程序中通过编程来实现。

驱动程序中要设置一个函数,来接收和处理上位机发送来的升级指令(如“XUPDT”)。在这个函数中,首先停止USB设备、去初始化DeInit,设置一个存储在RAM中的标志,比如dfu_flag。最后调用NVIC_SystemReset执行软件复位。

static void HandleUpdtCommand(void){ printf("Entering DFU mode for firmware update...\r\n"); extern USBD_HandleTypeDef hUsbDeviceFS; USBD_Stop(&hUsbDeviceFS); USBD_DeInit(&hUsbDeviceFS); extern volatile uint32_t dfu_flag; dfu_flag = 0x97E9; // Software reset to enter DFU mode __disable_irq; NVIC_SystemReset;}

定义一个全局变量dfu_flag,存储在RAM中并初始化为0.

__attribute__((used, section(".dfu_flag"))) volatile uint32_t dfu_flag = 0;

编写一个检查dfu_flag并判断是否该进入DFU的函数,在main函数的第一行调用。

static void CheckAndEnterDFUMode(void){ extern volatile uint32_t dfu_flag; if (dfu_flag == 0x97E9) { dfu_flag = 0x0000; //reset flag __set_MSP(*((uint32_t*) 0x1FFFD800)); // system memory start ((void (*)(void)) (*((uint32_t*) 0x1FFFD804))); //reset vector }}

由于是软件复位后进入DFU,官方教程上那些管理时钟、中断....都可以省掉了,因为系统尚未初始化那些东西。

进入DFU的流程:在上位机发送“XUPDT”启动固件更新后,下位机执行软件复位,进入CheckAndEnterDFUMode,检查dfu_flag并进入DFU模式。普通的启动,由于dfu_flag不满足条件,CheckAndEnterDFUMode直接返回。

上位机可以用STM32CubeProgrammer进行固件更新。启动软件后,端口类型选择USB,刷新端口。如果有DFU设备可用,会显示端口名称和序列号。点击连接。然后就可以烧录新固件了。

来源:小夏科技讲堂

相关推荐