# OTA_bootloader **Repository Path**: lxp1278100188/ota_bootloader ## Basic Information - **Project Name**: OTA_bootloader - **Description**: 远程升级OTA - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2026-07-16 - **Last Updated**: 2026-11-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: OTA, bootloader, CAN, LoRa, STM32F1 ## README # OTA Bootloader ![Flash](https://img.shields.io/badge/Flash-64KB-2496ED) ![Language](https://img.shields.io/badge/Language-C-00599C) ![OTA](https://img.shields.io/badge/OTA-Firmware%20Update-2EA44F) ![CAN](https://img.shields.io/badge/Update-CAN-FF6F00) ![LoRa](https://img.shields.io/badge/Update-LoRa%20LLCC68-1E90FF) ## 项目简介 基于 STM32F103C8T6 的 OTA 升级工程,支持两种升级方式: - 有线升级:CAN - 无线升级:LoRa(LLCC68) 开发环境:Keil MDK5 + STM32CubeMX + STM32 HAL 库。 ## 目录结构 ```text bootloader_gitee ├── 00_upperComputer_CAN # CAN 模拟上位机,发送更新程序 ├── 00_upperComputer_LoRa # LoRa 模拟上位机,发送更新程序 ├── 01_apptest_CAN # 下位机 A 区,CAN 更新接收端 ├── 01_apptest_LoRa # 下位机 A 区,LoRa 更新接收端 ├── 02_Bootloader演示 # 串口 Bootloader 入门演示 ├── 03_企业级Bootloader # 下位机 B 区,最终 OTA Bootloader ├── 04_Bootloader_Reset # 恢复默认出厂/救援程序 ├── app_example_LED1.0 # 模拟更新程序 v1.0 └── app_example_LED2.0 # 模拟更新程序 v2.0 ``` `02_Bootloader演示` 是早期串口直接写 Flash 的演示工程,分区规则与最终 CAN/LoRa 方案不同,仅用于学习。 ## Flash 分区 F103C8T6 总 Flash 为 64KB,地址范围 `0x08000000 - 0x0800FFFF`,Flash 页大小为 1KB。 | 区域 | 地址范围 | 大小 | 对应工程 | |---|---|---|---| | B 区 | `0x08000000 - 0x08003FFF` | 16KB | `03_企业级Bootloader` | | Reset 区 | `0x08004000 - 0x08007FFF` | 16KB | `04_Bootloader_Reset` | | A 区 | `0x08008000 - 0x0800FFFF` | 32KB | `01_apptest_CAN`、`01_apptest_LoRa`、LED 示例 | ## Keil IROM 配置 打开 `Options for Target -> Target -> Read/Only Memory Areas -> IROM1`,按以下地址配置: | 工程 | IROM Start | IROM Size | |---|---|---| | `03_企业级Bootloader` | `0x08000000` | `0x4000` | | `04_Bootloader_Reset` | `0x08004000` | `0x4000` | | `01_apptest_CAN` | `0x08008000` | `0x8000` | | `01_apptest_LoRa` | `0x08008000` | `0x8000` | | `app_example_LED1.0` | `0x08008000` | `0x8000` | | `app_example_LED2.0` | `0x08008000` | `0x8000` | IRAM 保持默认:起始地址 `0x20000000`,大小 `0x5000`。 注意:仓库中部分 `.uvprojx` 当前仍是默认全 Flash 配置 `0x08000000 / 0x10000`。使用前需要按上表修改 IROM,防止 Bootloader、Reset、App 互相覆盖。编译后可以在生成的 `.sct` 或 `.map` 中确认实际链接地址。 ## 上位机准备 `00_upperComputer_CAN` 和 `00_upperComputer_LoRa` 是模拟上位机发送端,主程序按全片地址 `0x08000000 / 0x10000` 编译运行。 发送端程序会从自身 Flash 的 `0x08008000` 读取待发送 bin: 1. 先烧录上位机主程序。 2. 再将待发送的更新包烧录到同一颗芯片的 `0x08008000`。 3. 示例程序默认发送长度 3864 字节,即 LED 示例 bin 的长度。 4. 更换更新包时,需要同步修改上位机中的 `receive_all_len`。 ## CAN 升级流程 1. 下位机 A 区 `01_apptest_CAN` 通过串口 `PA9/PA10` 等待 `cmd`,波特率 115200。 2. 收到 `cmd` 后,A 区程序通过 CAN 发送升级请求 `yes`。 3. 上位机收到 `yes` 后,从 `0x08008000` 读取 bin,通过 CAN 分帧发送。 4. CAN 通信约定: - 升级请求:标准 ID `0`,数据 `yes` - 升级数据:标准 ID `1`,每帧 8 字节 - 数据结束后发送 CRC:标准 ID `1`,4 字节,小端序 - CAN1 重映射到 PB8/PB9,波特率 200 kbit/s 5. 下位机暂存数据到 RAM,2 秒无新数据后认为接收结束。 6. CRC 校验通过后,将更新包写入 W25Q64,并将更新标志写入 AT24C02,然后复位。 7. 复位后 `03_企业级Bootloader` 检测到更新标志,从 W25Q64 读取更新包并写入 A 区 Flash,最后跳转到 `0x08008000`。 ## LoRa 升级流程 流程与 CAN 一致,只是传输介质不同: 1. `01_apptest_LoRa` 串口收到 `cmd` 后,通过 LoRa 发送 `yes`。 2. 上位机收到 `yes` 后,从 `0x08008000` 读取 bin。 3. 每次 LoRa 发送 100 字节,间隔 100ms。 4. 数据发送完成后等待 3.1 秒,再发送 4 字节 CRC。 5. 下位机 3 秒无新数据后认为接收结束。 6. CRC 校验通过后写入 W25Q64 和 AT24C02,复位后由 B 区 Bootloader 写入 A 区。 LoRa 参数以 `00_upperComputer_LoRa` 和 `01_apptest_LoRa` 的 `dvc_Lora.h` 为准: - LLCC68 - 915MHz - SF9 - 125kHz - CR 4/5 - 同步字 `0x3444` - 显式包头 - CRC 开启 ## 恢复默认出厂流程 `03_企业级Bootloader` 启动时会检查 AT24C02: - 有更新标志:将 W25Q64 中的更新包写入 A 区,然后跳转 A 区。 - 无更新标志:直接跳转 A 区。 - 启动后 3 秒内按下按键:跳转到 Reset 区 `0x08004000`,即 `04_Bootloader_Reset`。 `04_Bootloader_Reset` 是恢复默认出厂程序,通过串口等待: ```text start:len ``` 收到命令后,接收长度为 `len` 的 bin,将其写入 A 区 `0x08008000`,完成后跳转到 A 区 App。 ## 外部存储布局 - W25Q64: - `0x000000`:元数据,8 字节,依次为更新包地址和长度,小端序 - `0x001000`:更新包数据 - AT24C02: - `0x10`:更新状态 - `0x11 - 0x12`:校验密钥,默认 `0x5A6B` ## 使用流程 1. 按上表修改各工程的 Keil IROM,重新编译。 2. 首次烧录时,按地址依次烧录 `03_企业级Bootloader`、`04_Bootloader_Reset`、A 区 App。 3. 上位机板烧录发送端主程序,并将 `app_example_LED1.0` 或 `app_example_LED2.0` 烧录到 `0x08008000`。 4. 连接 CAN 或 LoRa。 5. 向下位机串口发送 `cmd`,开始升级。 6. 通过 LED1.0 和 LED2.0 的不同闪烁频率确认升级结果。 ## 注意事项 - A 区 App 启动时必须设置 `SCB->VTOR = 0x08008000`,示例工程已经包含该逻辑。 - 当前 `01_apptest` 的 RAM 接收缓冲区为 8KB,适合当前 LED 小程序演示;实际产品如果 App 超过 8KB,需要改为分块接收或直接写入外部 Flash。 - 工程中部分注释写有 A 区 48KB 或 `APP_END_ADDR = 0x08080000`,这是从大容量芯片工程复制过来的。F103C8T6 应按 64KB 总容量处理,A 区结尾为 `0x0800FFFF`。 - LoRa 链路当前没有 ACK 和断点续传,实际产品建议增加帧序号、ACK、超时重传和版本号校验。 ## 使用说明 1. 上位机开发板负责发送更新程序 2. app开发板负责检查更新,并接收更新程序 3. app开发板的flash分为B区(16K)-恢复默认出厂工程(16K)-A区(芯片剩余flash大小) 4. 主控芯片为f103c8t6 5. LED两个版本用于充当OTA整体更新流程的app 6. 升级方式分为有线-CAN / 无线-LoRa #### 注意 - A区工程中不更新时为PA8的LED闪烁,可以选择更新1.0版本(PA1 LED闪烁)或2.0版本(PA2 LED闪烁) - 1.0和2.0更新程序仅作为升级成功的演示,内部无OTA接收逻辑 #### 笔记连接 OTA:https://app.yinxiang.com/fx/cab3b86b-bb70-4223-8ae4-0816838fdf1f