feat(Puya-PY32F040): add OTA dual-project codegen template

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-18 18:56:19 +08:00
co-authored by Cursor
commit 62eb0199ed
498 changed files with 329164 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
# PY32F040 OTA 开发框架
基于 PY32F040 的 OTA 双工程开发框架。**Bootloader 与 App 是两个独立的 Keil 工程**
共用顶层 `Shared/`OTA 契约)与 `Drivers/`(厂商 SDK)。
支持三种可配置 OTA 模式(`Shared/ota_config.h`):
| 模式 | 说明 |
|------|------|
| 单备份 | BAK 下载 → 校验 → 拷贝覆盖主区,最省 Flash |
| 双备份 + RAM | A/B 交换,新固件崩溃可自动回滚 |
| 双备份 + 暂存区 | A/B 交换 + Flash scratch,升级最快、掉电恢复最稳 |
协议对接 jb_protocol0x30/0x32/0x34),用户层在 `Protocol/jb_product.c` 对接。
详细设计见 [`Doc/OTA_AB_双备份升级设计.md`](Doc/OTA_AB_双备份升级设计.md)。
---
## 目录结构
```
PY32F040开发框架/
├── App/ APP 工程(链接 0x08003000
│ ├── Src/ main.c / application.c / system_py32f040.c
│ ├── Core/ ota_ab / iwdg / app_boot / jb_uart 等
│ ├── Protocol/ jb_protocol + jb_product(协议与用户层)
│ ├── Utils/
│ └── MDK-ARM/ project.uvprojx
├── Bootloader/ Bootloader 工程(链接 0x08000000
│ ├── Src/ boot_main.c
│ ├── Code/ flash.h(实现见 Shared/flash.c
│ └── MDK-ARM/ Bootloader.uvprojx
├── Drivers/ 厂商 HAL/CMSIS(只读,勿改)
├── Shared/ OTA 契约【单一真源】
│ ├── ota_config.h 三模式配置入口
│ ├── flash.c 状态区读写
│ ├── crc32.c/h 固件 CRC32
│ ├── iwdg_config.h 看门狗超时参数
│ └── log.h
├── tools/ 构建与打包脚本
├── Output/ 构建产物(git 忽略)
└── Doc/ 设计文档
```
两工程通过 `..\..\Shared``..\..\Drivers` 引用共享层,**彼此零依赖**。
---
## 快速开始
### 环境要求
- Keil MDK(含 PY32F040 器件包)
- Python 3(用于 `tools/` 脚本,可选)
### 1) 一键构建
```bat
build.bat
```
```bat
python tools\build_all.py
```
产物输出到 `Output/`
- `bootloader.hex|bin` — 0x08000000
- `app.hex|bin` — 0x08003000
- 末尾打印 `app.bin`**fwCrc32**0x30 请求需携带)
### 2) Keil 单独打开
| 工程 | 工程文件 |
|------|----------|
| Bootloader | `Bootloader/MDK-ARM/Bootloader.uvprojx` |
| App | `App/MDK-ARM/project.uvprojx` |
### 3) 修改 OTA 模式
只改 `Shared/ota_config.h` 中的 `OTA_BACKUP_MODE` / `OTA_SWAP_STRATEGY`
然后重新构建两工程(无需手动同步两份代码)。
### 4) 打包发给用户
```bat
tools\pack_bootloader.bat → Output\bootloader_package.zip
tools\pack_app.bat → Output\app_package.zip
```
zip 内布局:`Bootloader|App/` + `Drivers/` + `Shared/` 平级。
对方解压后直接用 Keil 打开 `.uvprojx` 即可编译(已剔除 `.o/.d` 等中间产物)。
> 需解压整个 zip,保持相对目录结构,不要只拷贝子文件夹。
### 5) 出厂烧录
```bat
python tools\merge_hex.py → Output\merged_single.hex
```
合并 Bootloader + App 为单一 hex。纯 OTA 远程升级只需 `app.bin`
---
## 关键注意点
- **Shared/ 是唯一真源**:改 OTA 布局/状态机只改此处;`flash.h` 两工程各有一份(适配各自头文件路径)。
- **Drivers/ 只读**:厂商 SDK,两工程共用,勿修改。
- **链接地址**:由 Keil Target → ROM1`OCR_RVCT4`)决定,须与 `Shared/ota_config.h``OTA_RUN_ADDR_BASE`0x08003000)一致。
- **`.bat` 脚本保持纯 ASCII**:cmd 按 GBK 解析,含中文可能乱码。
- **IWDG**Bootloader 跳转前启动看门狗;App 在 `app_boot.c` 中接管并喂狗,时钟配置不可关 LSI。
---
## 开发入口(常用文件)
| 目的 | 文件 |
|------|------|
| 改 OTA 模式/布局 | `Shared/ota_config.h` |
| OTA 下载逻辑 | `App/Core/ota_ab.c` |
| 协议 OTA 回调 | `App/Protocol/jb_product.c` |
| Bootloader 状态机 | `Bootloader/Src/boot_main.c` |
| App 启动流程 | `App/Core/app_boot.c` |
| 应用主循环 | `App/Src/application.c` |