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')
相关推荐
虎王物联3 小时前
STM32 HAL库串口DMA空闲中断:高效接收不定长Modbus数据帧
stm32·单片机·嵌入式硬件·dma·modbus
自小吃多3 小时前
DXF文件导入与PCB板框定义笔记
笔记·嵌入式硬件
SUNNYSPY0013 小时前
AO4402-ASEMI便携设备电源开关AO4402
单片机
单片机仿真设计6 小时前
【proteus仿真】基于 STC89C52 单片机家用智能台灯设计(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·毕设
2601_950790686 小时前
深圳国产单片机厂商怎么选?技术能力与服务能力检查表
单片机·嵌入式硬件·国产mcu·芯片厂商·深圳单片机·单片机选型
hongmai6668888 小时前
MP2348GTL-Z:这颗24V/4A同步降压芯片,把性能和体积平衡得恰到好处
c语言·开发语言·arm开发·单片机·5g
笨笨饿8 小时前
#135_代码中的类型重定义艺术:从基础封装到函数类型设计
开发语言·stm32·单片机·嵌入式硬件·mcu·物联网·嵌入式实时数据库
西城微科方案开发8 小时前
高精度低功耗胎压计方案——气压表解决方案
单片机·嵌入式硬件
LavaLin0110 小时前
STM32H562RGT6 与 STM32F722RET6 规格对比
stm32
VALENIAN瓦伦尼安教学设备10 小时前
设备状态检测振动分析实训台案例分析
大数据·数据库·人工智能·嵌入式硬件·算法