stm32 usb升级 模拟u盘 固件更新 芯片:stm32f103 功能介绍:stm32的usb口连接到电脑,boot程序会自动模拟出一个u盘用于升级。 将需要升级的bin文件粘贴到模拟出来的u盘内,升级完成。 资料包:boot程序,appdemo程序,原理图

最近在折腾STM32F103的USB固件升级方案,发现用U盘模拟方式升级真的挺方便。插上USB线就能当U盘用,直接把bin文件往里一扔就完成升级,这操作对产线工人简直不要太友好。今天咱们就掰开揉碎了讲讲这个实现套路。

先看整体流程:芯片上电先运行Bootloader,用USB_MSC协议把自己伪装成U盘。这时候电脑上会出现个可移动磁盘,我们把编译好的APP固件(.bin)复制进去。Bootloader检测到文件写入后,擦除Flash,把新固件烧录到指定地址,最后跳转到APP程序执行。

关键代码藏在usbdstorageif.c这个文件里。咱们得实现SCSI命令处理,特别是处理WRITE_10命令时的骚操作:

int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
    // 检测到固件写入特定扇区时
    if(blk_addr == FIRMWARE_START_SECTOR) {
        firmware_size = blk_len * STORAGE_BLK_SIZ;
        // 激活固件更新标志
        update_flag = 1;
    }
    // 实际写入SD卡或Flash...
}

这里有个坑要注意——Windows系统往U盘写文件时并不是连续写入,可能先写FAT表再写文件内容。所以不能简单检测到文件写入就立即升级,得等文件传输完全完成。我一般用定时器做个延时检测,5秒内没有新数据写入再触发升级流程。

Flash烧写部分得处理好跨页写入,STM32F103的Flash页是1K大小。看这个擦除代码:

void FLASH_Program(uint32_t Address, uint32_t Data)
{
    FLASH_Unlock();
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR);
    
    while(Address < APP_ADDRESS + firmware_size) {
        if(Address % FLASH_PAGE_SIZE == 0) {
            FLASH_ErasePage(Address); // 按页擦除
        }
        FLASH_ProgramWord(Address, *(uint32_t*)Data);
        Address += 4;
        Data += 4;
    }
    FLASH_Lock();
}

最刺激的还是从Bootloader跳转到APP的临门一脚操作,这个汇编函数是关键:

__asm void JumpToApp(uint32_t appAddress)
{
    LDR SP, [R0]       // 加载新堆栈指针
    LDR PC, [R0, #4]   // 加载复位向量
}

但有个细节容易翻车——跳转前必须关闭所有外设中断。我有次忘了关USB中断,直接导致跳转后程序跑飞。后来加了这个保护:

void System_JumpToApp(void)
{
    __disable_irq(); // 关闭全局中断
    HAL_RCC_DeInit();
    HAL_DeInit();
    JumpToApp(APP_ADDRESS);
}

实战中还遇到个奇葩问题:Windows默认给U盘开写入缓存,导致文件看似复制完成实际数据还没完全写入。解决方法是在复制完bin文件后,用批处理执行"sync"命令强制刷新缓存,或者让用户手动弹出U盘。

这个方案实测升级速度能达到60KB/s左右,比串口IAP快不少。不过要注意bootloader不能超过16K,毕竟F103的Flash总共才64K或128K。建议用-Os优化编译,把USB库里不必要的描述符都砍掉。

最后提个安全机制:最好在APP程序开头加个强制进入升级模式的软复位指令,配合按键检测实现双保险。这样即使升级失败,还能通过按键触发重新进入bootloader模式。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐