You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32自定义Bootloader开发及RS485在线编程问题咨询

自定义STM32 RS-485 Bootloader开发疑问解答

背景与方案概述

两块搭载STM32的开发板通过RS-485互联(各板配备UART转RS-485收发器),因无法修改PCB使用ST官方Bootloader及BOOT0引脚,需开发自定义Bootloader。

Flash分区规划

  • B-1 Flash分为3部分:
    • 20KB:Bootloader
    • 120KB:B-2应用缓冲区
    • 360KB:B-1主应用
  • B-2 Flash分为2部分:
    • 20KB:Bootloader
    • 100KB:主应用

Bootloader执行逻辑

// B1: starts from bootloader 
for (5 seconds) {
    // check for the boot command from UART 
    if (command received) {
        // send boot and reset command to B-2 and receive ack
        // start the boot mode
        while (boot mode not aborted) {
            // receive command packet containing address
            if (command == header && address == B1) {
                // prompt for the main .hex file and store it in B-1 partition
            } else if (command == header && address == B2) {
                // prompt for the main .hex file and store it in B-2 partition
                // send header and the app to B-2 using rs-485 port
            } else if (command == abort) {
                break from while loop
            }
        }
    } else {
        // do nothing
    }
}
// jump to main application

疑问与解答

疑问1:无GPIO连接时,能否通过Flash标志位激活B-2的Boot模式?

完全可行,具体实现思路:

  • 在B-2的Flash中预留一块独立的标志存储区域(建议选Bootloader分区内的空闲扇区,或单独划分一个小扇区,确保不会被主应用或Bootloader的擦写操作覆盖)
  • B-2的Bootloader启动后,优先检查该标志位:
    • 若标志位为预设的“Boot模式触发值”,则跳过主应用跳转,进入RS-485等待接收的Boot状态
    • 若标志位正常,则直接跳转至主应用
  • 触发流程:B-1发送Boot命令时,先通过RS-485向B-2的主应用发送指令,让B-2主应用写入标志位,随后执行软复位;B-2复位后进入Bootloader,检测到标志位即进入Boot模式,操作完成后需清除标志位,避免下次启动误触发

疑问2:能否直接将UART输入数据流写入应用Flash区域?

不能直接按示例代码操作,STM32 Flash写入有严格的硬件约束,示例代码存在以下问题:

  1. Flash写入前必须擦除:STM32 Flash只能从1改写为0,写入前必须先擦除对应扇区(扇区大小依STM32型号而定),直接写入会导致数据异常或硬件错误
  2. 地址访问限制:Flash属于只读存储区域,不能直接将UART接收的指针指向Flash地址,需先将数据接收至RAM缓冲区,再通过Flash编程API写入
  3. 无数据校验:逐字节直写缺乏校验机制,传输过程中出现错误无法及时发现

正确的操作流程示例:

// 1. 先将UART数据接收至RAM缓冲区
uint8_t ram_buf[APP_BUFFER_SIZE];
for (uint32_t i = 0; i < size_of_app; i++) {
    HAL_UART_Receive(&uartPort, &ram_buf[i], 1, timeout);
}

// 2. 校验数据完整性(如CRC、校验和)
if (verify_data(ram_buf, size_of_app) != OK) {
    // 校验失败,执行错误处理
    return;
}

// 3. 擦除目标Flash扇区
uint32_t flash_addr = B2_APP_FLASH_MEMORY_PARTITION_START_ADDRESS;
FLASH_EraseInitTypeDef erase_init;
erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
erase_init.Sector = get_sector_from_address(flash_addr); // 根据地址获取对应扇区
erase_init.NbSectors = get_sector_count(size_of_app); // 计算需要擦除的扇区数量
erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 匹配芯片供电电压范围
uint32_t sector_error;
if (HAL_FLASHEx_Erase(&erase_init, &sector_error) != HAL_OK) {
    // 擦除失败,执行错误处理
    return;
}

// 4. 将RAM缓冲区数据写入Flash
for (uint32_t i = 0; i < size_of_app; i += 4) { // 按字写入,提升效率
    uint32_t data = *(uint32_t*)(ram_buf + i);
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_addr + i, data) != HAL_OK) {
        // 写入失败,执行错误处理
        return;
    }
}

内容的提问来源于stack exchange,提问作者mehdi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:10:25