STM32L051 的 串口升级

STM32L051 的 串口升级(UART Bootloader / IAP)


一、STM32L051 串口升级总体方案

1、系统架构

复制代码
Flash 布局(64 KB)
┌─────────────────────┐ 0x08000000
│ Bootloader (8 KB)    │ ← 上电首先运行
├─────────────────────┤ 0x08002000
│ Application A       │ ← 正常运行区
├─────────────────────┤ 0x0800C000
│ Application B       │ ← 备用/升级区(可选)
└─────────────────────┘ 0x08010000

推荐方案

  • Bootloader + 单 App(覆盖升级)
  • 双分区(A/B)

二、启动流程(Bootloader 逻辑)

text 复制代码
上电复位
   ↓
Bootloader 启动
   ↓
检查升级标志(Flash / GPIO / 命令)
   ↓
是否需要升级?
   ├─ 是 → 接收串口固件 → 擦写 Flash → 跳转
   └─ 否 → 直接跳转到 App

三、Flash 分区与关键地址

区域 起始地址 大小
Bootloader 0x08000000 8 KB
Application 0x08002000 56 KB

升级标志位(放在 Flash 末尾)

c 复制代码
#define UPDATE_FLAG_ADDR  0x0800FF00
#define UPDATE_MAGIC_NUM  0x12345678

四、Bootloader 核心代码(HAL 库)

1、串口初始化(UART1)

c 复制代码
void UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    HAL_UART_Init(&huart1);
}

2、跳转到 APP

c 复制代码
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;

void Jump_To_App(uint32_t app_addr)
{
    __disable_irq();

    JumpAddress = *(__IO uint32_t*)(app_addr + 4);
    JumpToApplication = (pFunction)JumpAddress;

    __set_MSP(*(__IO uint32_t*)app_addr);
    JumpToApplication();
}

3、 Flash 擦除 & 写入

c 复制代码
void Flash_Write(uint32_t addr, uint8_t *data, uint32_t len)
{
    HAL_FLASH_Unlock();

    for (uint32_t i = 0; i < len; i += 4)
    {
        uint32_t word = data[i] |
                       (data[i+1] << 8) |
                       (data[i+2] << 16) |
                       (data[i+3] << 24);

        HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + i, word);
    }

    HAL_FLASH_Lock();
}

五、串口升级协议(简单可靠)

帧格式(推荐)

复制代码
| HEAD | CMD | LEN | DATA | CRC |
| 0xAA | 0x01|   N | ...  | CRC |
CMD 功能
0x01 开始升级
0x02 发送数据
0x03 结束升级
0x04 校验成功

接收数据示例

c 复制代码
void Receive_Firmware(void)
{
    uint8_t buf[256];
    uint32_t writeAddr = APP_START_ADDR;

    while (1)
    {
        HAL_UART_Receive(&huart1, buf, 132, HAL_MAX_DELAY);

        if (buf[0] == 0xAA && buf[1] == 0x02)
        {
            Flash_Write(writeAddr, &buf[4], 128);
            writeAddr += 128;
        }
        else if (buf[1] == 0x03)
        {
            break;
        }
    }
}

参考代码 stm32l051的串口升级程序 www.youwenfan.com/contentcsv/72126.html

六、APP 程序注意事项

1、中断向量偏移

c 复制代码
SCB->VTOR = FLASH_BASE | 0x2000;

2、Linker 修改(Keil)

复制代码
ROM: 0x08002000
Size: 0xE000

七、升级触发方式

方式 说明
串口命令 PC 下发升级指令
GPIO 按键 BOOT 引脚拉高
软件标志 写入 Flash 标志
看门狗超时 异常重启升级

八、防变砖设计

CRC 校验
升级失败自动回滚
Bootloader 不升级
写保护 Option Bytes
掉电保护(页写完成才更新标志)


九、PC 端升级工具

python 复制代码
import serial

ser = serial.Serial('COM3', 115200)

def send_bin(file):
    with open(file, 'rb') as f:
        while True:
            data = f.read(128)
            if not data:
                break
            ser.write(b'\xAA\x02\x80' + data)
    ser.write(b'\xAA\x03\x00')
相关推荐
210Brian1 小时前
蓝桥杯单片机学习笔记(十二):V2026 大模板构建(上)
单片机·学习·蓝桥杯
潜创微科技2 小时前
潜创微科技|沁恒微电子 (WCH) 官方授权代理商&方案商 一站式国产接口芯片解决方案
科技·嵌入式硬件
森利威尔电子-2 小时前
森利威尔 SL3037B 替换HT7463A/HT7463B 5.5-60V宽压 峰值 0.6A
单片机·嵌入式硬件·物联网·集成电路·芯片
fengfuyao9852 小时前
STM32 TIM8 两路互补PWM带死区控制程序
网络·stm32·嵌入式硬件
Jason_zhao_MR12 小时前
RK3576 MIPI Camera ISP调试:主观调优与工程实战(下)
stm32·嵌入式硬件·安全·系统架构·嵌入式
ACP广源盛1392462567315 小时前
iOS 27 开放 AI 生态@ACP#小型化扩展黄金风口,IX8008全面超越 ASM2806,铸就嵌入式 AI 扩展核心
人工智能·嵌入式硬件·macos·ios·计算机外设·objective-c·cocoa
smartpi_ai15 小时前
玩具产品从按键控制升级为语音控制:语音模块与MCU串口通信实战
单片机·嵌入式硬件
BreezeJuvenile17 小时前
【STM32】时钟摘取法
stm32·单片机·嵌入式硬件
崇山峻岭之间17 小时前
单片机GPIO配置
单片机·嵌入式硬件