使用 M997 在 Marlin 中实现 STM32 DFU 引导加载程序固件升级

Marlin 实现了 M997 命令,旨在将主板切换到固件升级模式。

所有 STM32 变体都有一个集成的(硬编码的 - 所以无需自己刷写)引导加载程序,它出了名地难以激活。

然而,Marlin 在 STM32 上将 M997 实现为只是重启

flash_firmware_dfu.cpp
void flashFirmware(const int16_t) { HAL_reboot(); }

这只有在你使用板上的自定义引导加载程序时才有效 - 然而,它不使用 STM32 集成的引导加载程序。

以下代码在 STM32F446(BigTreeTech Octopus V1)上测试过,但应该适用于任何 STM32 变体。它基于 StackOverflow 上 Dave Hyland之前的工作替换 Marlin/src/HAL/STM32/HAL.cpp 中的默认 flashFirmware() 函数

flash_firmware_instructions.sh
void flashFirmware(const int16_t) {
    HAL_RCC_DeInit();
    HAL_DeInit();

    __HAL_REMAPMEMORY_SYSTEMFLASH();

    // arm-none-eabi-gcc 4.9.0 不能正确内联这个
    // MSP 函数,所以我们在这里显式写出。
    //__set_MSP(*((uint32_t*) 0x00000000));
    __ASM volatile ("movs r3, #0\nldr r3, [r3, #0]\nMSR msp, r3\n" : : : "r3", "sp");

    ((void (*)(void)) *((uint32_t*) 0x00000004))();

    // 这永远不会被执行
    HAL_reboot();
}

注意我们在末尾留下了 HAL_reboot() 调用作为保护措施,以防前面的调用失败。

在我的 BigTreeTech Octopus V1 (STM32F446) 上,使用此代码,你可以成功进入集成的 DFU 引导加载程序。

另请参阅我们之前关于如何在 DFU 引导加载程序模式下使用 STM32 的文章:


Check out similar posts by category: 3D Printing, C/C++, STM32