142 lines
4.3 KiB
Markdown
142 lines
4.3 KiB
Markdown
# 汇编 Bootloader 出厂固件恢复验证记录
|
||
|
||
## 1. 验证目的
|
||
|
||
验证当 STM8S003F3P6TR 内部应用 Flash 没有主程序时,汇编 Bootloader 能否从外部 W25Q80BV 读取出厂固件,完成内部应用区恢复,并跳转到主程序执行。
|
||
|
||
## 2. 当前地址规划
|
||
|
||
| 区域 | 地址范围 | 说明 |
|
||
|---|---:|---|
|
||
| Bootloader | `0x8000~0x84FF` | 固定汇编 Bootloader 区域 |
|
||
| 主程序 | `0x8500~0x9FFF` | 汇编主程序运行区域 |
|
||
| 出厂固件 | W25Q80BV `0x000000~0x001FFF` | 最大 8KiB |
|
||
| 出厂元数据 | W25Q80BV `0x002000~0x002FFF` | 4KiB 区域 |
|
||
|
||
## 3. 外部 Flash 内容验证
|
||
|
||
独立 SPI 测试固件已经读取并校验出厂镜像,串口输出如下:
|
||
|
||
```text
|
||
SPI TEST START
|
||
JEDEC OK
|
||
MAGIC: 31434146
|
||
LENGTH: 06AE
|
||
VERSION: 0100
|
||
STORED CRC: DF89
|
||
VALID: A5
|
||
CALC CRC: DF89
|
||
FACTORY IMAGE PASS
|
||
```
|
||
|
||
因此确认:
|
||
|
||
- W25Q80BV JEDEC ID 读取正常;
|
||
- 出厂固件魔数正确;
|
||
- 出厂固件长度为 `0x06AE`;
|
||
- 出厂固件版本为 `0x0100`;
|
||
- 元数据保存 CRC 为 `0xDF89`;
|
||
- Bootloader 有效标志为 `0xA5`;
|
||
- 单片机重新计算 CRC 后仍为 `0xDF89`。
|
||
|
||
## 4. Bootloader 恢复流程
|
||
|
||
当前汇编 Bootloader 的出厂恢复流程为:
|
||
|
||
1. 设置系统时钟为 16MHz;
|
||
2. 初始化 SPI1;
|
||
3. 读取并检查 W25Q80BV JEDEC ID;
|
||
4. 检查出厂固件元数据;
|
||
5. 按 `CRC-16/MODBUS` 逐字节校验出厂固件;
|
||
6. 解锁 STM8 程序 Flash;
|
||
7. 对 `0x8500~0x9FFF` 应用区逐字节擦除;
|
||
8. 从 W25Q80BV `0x000000` 开始逐字节搬运到内部 Flash `0x8500`;
|
||
9. 回读内部 Flash,并与外部出厂镜像逐字节比较;
|
||
10. 跳转到主程序复位向量执行。
|
||
|
||
## 5. 现场验证结果
|
||
|
||
验证前先清除内部 Flash 的主程序区域,使 `0x8500` 之后没有有效主程序。重新烧录 Bootloader 并上电后,设备能够自动完成出厂固件搬运,随后主程序正常启动,并输出蓝牙初始化相关信息:
|
||
|
||
```text
|
||
AT+ROLE
|
||
AT+ROLE2
|
||
AT+ROLE
|
||
AT+ROLE2
|
||
AT+ROLE
|
||
```
|
||
|
||
验证结论:
|
||
|
||
**内部 Flash 无主程序时,Bootloader 自动从 W25Q80BV 搬运出厂固件并成功启动主程序,功能验证通过。**
|
||
|
||
## 6. 调试代码清理
|
||
|
||
为便于现场确认,曾临时加入 Bootloader UART1 阶段输出。恢复流程验证完成后,已经删除:
|
||
|
||
- Bootloader UART1 初始化代码;
|
||
- 临时阶段字符输出;
|
||
- 元数据诊断输出;
|
||
- CRC、擦除、搬运、回读和跳转诊断输出。
|
||
|
||
正式 Bootloader 不再占用 UART1 发送调试功能。
|
||
|
||
## 7. 本次修正的关键问题
|
||
|
||
### 7.1 元数据长度解析
|
||
|
||
固件长度字段是 4 字节高字节在前:
|
||
|
||
```text
|
||
00 00 06 AE
|
||
```
|
||
|
||
前两个字节必须为 `0x00`,后两个字节才是实际长度 `0x06AE`。
|
||
|
||
### 7.2 CRC 多项式
|
||
|
||
`CRC-16/MODBUS` 反射算法使用多项式 `0xA001`。在当前两个字节寄存器实现中:
|
||
|
||
```text
|
||
高字节异或:0xA0
|
||
低字节异或:0x01
|
||
```
|
||
|
||
### 7.3 STM8 Flash 擦除方式
|
||
|
||
块擦除流程要求连续装载 4 个字节,并且关键步骤需要从 RAM 执行。当前 Bootloader 采用逐字节擦除方式,向应用区每个地址写入 `0x00`,每次等待 EOP 完成,避免块擦除流程在 Flash 中执行时卡住。
|
||
|
||
### 7.4 EOP 标志
|
||
|
||
当前项目使用的 STM8S003 寄存器定义中,`FLASH_IAPSR.EOP` 掩码为 `0x04`,即 bit2。Bootloader 按 bit2 检测擦除和写入完成状态。
|
||
|
||
## 8. 当前验证状态
|
||
|
||
### 8.1 已完成并通过
|
||
|
||
- 外部 W25Q80BV JEDEC ID 读取;
|
||
- 外部 Flash 出厂元数据读取;
|
||
- 出厂固件 CRC16 校验;
|
||
- 内部 Flash 无主程序时自动恢复出厂固件;
|
||
- 主程序复位向量 `0x8500` 损坏时自动恢复;
|
||
- 内部 Flash 应用区擦除;
|
||
- 出厂固件逐字节搬运;
|
||
- 内部 Flash 回读校验;
|
||
- Bootloader 成功跳转主程序;
|
||
- PA3 上电长按超过 5 秒恢复出厂固件;
|
||
- 恢复流程完成后主程序正常启动。
|
||
|
||
### 8.2 后续待验证
|
||
|
||
以下项目属于主程序 OTA 和整机联调范围,尚未作为当前 Bootloader 的最终验收依据:
|
||
|
||
- OTA 固件元数据处理;
|
||
- OTA 固件搬运和升级结果写回;
|
||
- OTA 分包丢失、CRC错误和断电恢复;
|
||
- 主程序向主机上报升级结果;
|
||
- ACS712 实际电流采样和电流故障判断;
|
||
- 蓝牙 Mesh 多设备完整联调;
|
||
- 继电器带实际负载的长期运行测试。
|
||
|
||
在上述主程序功能开始前,不应修改已经通过验证的 Bootloader 恢复流程。
|