# OTA 升级技术方案文档

## 1\. 引言

本文档详细描述了本项目（太阳能备份管理系统）中 OTA（Over-The-Air）远程固件升级功能的完整技术实现方案。OTA 升级是嵌入式系统的重要功能，确保设备能够在不人工干预的情况下远程更新固件，提高系统的维护效率和安全性。

本方案基于 MQTT 通信协议，通过云端下发升级命令，设备自动执行下载、校验、安装和重启流程。整个升级过程采用状态机设计，确保可靠性。

## 2\. 升级包格式

### 2.1 包结构设计

升级包采用分层压缩格式，确保传输效率和安全性：

```plaintext
远程升级包 (app_nccu.tar.gz)
├── app_nccu.tar.gz          # 实际应用固件包
├── pkg.sum                  # MD5校验文件
└── [可选] upgrade_script.sh # 升级脚本（本项目未使用）
```

### 2.2 内部固件包内容

`app_nccu.tar.gz` 包含完整的应用程序和配置文件：

```plaintext
/app/                        # 目标安装目录
├── nccu                     # 主应用程序
├── config/                  # 配置文件目录
├── lib/                     # 依赖库
└── [其他应用文件]
```

### 2.3 包命名规范

*   **下载文件名**：`LOCAL_UPGRADE_FIRMWARE_NAME` (定义为固定的本地文件名)
    
*   **解压后文件名**：`app_nccu.tar.gz`
    
*   **校验文件名**：`pkg.sum`
    

### 2.4 包大小限制

*   最大包大小：受限于 `/var/volatile` 目录空间（通常为 RAM 盘）
    
*   建议包大小：< 100MB（考虑解压时间和内存限制）
    

## 3\. 校验命令

### 3.1 MD5 校验机制

#### 3.1.1 校验文件格式 (`pkg.sum`)

```plaintext
MD5(app_nccu.tar.gz)= [32位十六进制MD5值]
```

例如：

```plaintext
MD5(app_nccu.tar.gz)= a1b2c3d4e5f678901234567890abcdef
```

#### 3.1.2 校验函数实现

```c
// 函数位置：sampler_system.c
BOOL DoMD5Chk_ForRemotePkg(BOOL bIsForCCU)
{
    // 读取 pkg.sum 文件
    // 计算 app_nccu.tar.gz 的实际 MD5
    // 比较校验值
    // 返回校验结果
}
```

#### 3.1.3 校验流程

1.  读取 `/var/volatile/pkg.sum` 文件内容
    
2.  计算 `/var/volatile/app_nccu.tar.gz` 的 MD5 值
    
3.  比较两个 MD5 值是否一致
    
4.  校验失败时记录错误日志并上报失败状态
    

### 3.2 文件存在性校验

在解压后进行基础校验：

```bash
# 检查必需文件是否存在
if [ ! -f "/var/volatile/app_nccu.tar.gz" ] || [ ! -f "/var/volatile/pkg.sum" ]; then
    # 校验失败处理
fi
```

### 3.3 校验失败处理

*   **状态上报**：`FIRMUPDATE_InstallFailed`
    
*   **日志记录**：详细记录校验失败原因
    
*   **清理操作**：删除下载的无效文件
    
*   **重置状态**：回到 `UPDOWN_IDLE` 状态
    

## 4\. 升级日志机制

### 4.1 日志分类

#### 4.1.1 系统日志 (通过 `LogOut` 函数)

```c
LogOut(MAIN_MODULE_SAMPLER, "Sys", LOG_TYPE_INFO,
    "Begin download firmware from URL[%s]!", url);

LogOut(MAIN_MODULE_SAMPLER, "Sys", LOG_TYPE_ERROR,
    "MD5 chk FAILED after downloaded from URL[%s]!", url);
```

#### 4.1.2 事件日志 (通过 `EVENT_TYPE_FIRMWARE_UPDATE`)

```c
EVENT_FIRMWAREUPDATE_STATUS evFirmUpdt;
evFirmUpdt.emUpdateStatus = FIRMUPDATE_Downloading;
SendMsg(pSys_Rough->hSampler, EVENT_TYPE_FIRMWARE_UPDATE, 
    EVENT_MSG_BEGIN, &evFirmUpdt, sizeof(EVENT_FIRMWAREUPDATE_STATUS));
```

### 4.2 日志级别定义

*   `LOG_TYPE_INFO`：正常操作信息
    
*   `LOG_TYPE_ERROR`：错误信息
    
*   `LOG_TYPE_WARING`：警告信息
    

### 4.3 关键日志点

1.  **开始下载**：记录下载 URL
    
2.  **下载进度**：通过 TRACE 记录下载状态
    
3.  **下载完成/失败**：记录结果和重试次数
    
4.  **校验开始/结果**：记录 MD5 校验过程
    
5.  **安装过程**：记录解压、文件替换操作
    
6.  **重启触发**：记录系统重启原因
    

### 4.4 日志存储位置

*   **运行时日志**：存储在内存或 `/var/log/`
    
*   **持久化日志**：可能通过专门的日志模块保存到 Flash
    

## 5\. 重启策略

### 5.1 重启时机控制

#### 5.1.1 充电状态检查

在准备重启前，检查所有充电枪状态：

```c
DATA_PROCESSOR* pDPR = (DATA_PROCESSOR*)((SAMPLER*)pSys_Rough->hSampler)->hDPR;
for(n = 0; n < 3; n++) {
    pDPR->Get(pSys_Rough->hSampler, GETTYPE_SP_VAR,
        201 + n, 101, &varV, 4);
    if((varV.emValue >= GUN_STATE_RESERVE_PENDING) &&
        (varV.emValue <= GUN_STATE_WAITING_END)) {
        // 正在充电，延迟重启
        return;
    }
}
```

#### 5.1.2 CCU 升级同步

如果升级包包含 CCU（充电控制器）固件：

```c
if(IsInclued_CCUFimrwarePkg(pSys_Rough)) {
    pSys_Rough->emDownloadStatus = UPDOWN_WAIT_REBOOT_AND_CCU;
    // 等待 CCU 升级完成后再重启主系统
}
```

### 5.2 重启执行流程

#### 5.2.1 发送重启事件

```c
EVENT_SYSTEM_EXIT evExit;
evExit.nExitType = SYS_EXIT_FIRMWAREUPDT;
SendMsg(pSys_Rough->hSampler, EVENT_TYPE_SYSTEM_EXIT, 
    EVENT_MSG_BEGIN, &evExit, sizeof(EVENT_SYSTEM_EXIT));
```

#### 5.2.2 系统级重启

重启由系统事件处理器处理，通常执行：

```bash
# 系统重启命令（在事件处理器中）
reboot
# 或
shutdown -r now
```

### 5.3 重启安全保障

#### 5.3.1 原子性保证

*   文件替换使用 `sync` 命令确保写入 Flash
    
*   重启前确保所有文件操作完成
    

#### 5.3.2 失败回滚机制

*   保留旧版本应用文件
    
*   启动脚本检测升级标志，失败时回滚
    

#### 5.3.3 重启超时保护

*   设置 watchdog 确保重启过程不卡死
    
*   重启失败时自动恢复到安全模式
    

## 6\. 完整升级流程图

```plaintext
云端下发升级命令 (MQTT S_404)
        ↓
设备解析命令 → 生成 A_BLOB_UPDATEFIRMWARE_CMD
        ↓
写入 DAI 控制参数
        ↓
采样器检测到新命令
        ↓
等待 dtRetrieveDate 时间到达
        ↓
开始下载固件包 (HTTP/FTP)
        ↓
下载中... (状态: UPDOWN_PENDING)
        ↓
下载完成/失败？
    ↓ (失败)
重试 (最多 nDownloadRetries 次)
    ↓ (成功)
解压到 /var/volatile/
        ↓
检查文件存在性 (app_nccu.tar.gz + pkg.sum)
        ↓
MD5 校验
        ↓
校验通过？
    ↓ (失败)
上报失败状态，清理文件
    ↓ (成功)
解压到 /app 目录 (tar -zxf ... -C /app)
        ↓
sync 确保写入完成
        ↓
检查充电状态 (是否可以安全重启)
        ↓
检查 CCU 升级状态
        ↓
发送重启事件 (EVENT_SYSTEM_EXIT)
        ↓
系统重启，完成升级
```

## 7\. 配置参数说明

### 7.1 升级相关配置项

| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `nDownloadRetries` | int | 3 | 下载重试次数 |
| `nRetryInterv` | int | 60 | 重试间隔(秒) |
| `dtRetrieveDate` | time\_t | 0 | 升级开始时间 |

### 7.2 超时设置

*   **下载超时**：1800 秒 (30 分钟)
    
*   **重启等待**：检查充电状态间隔
    
*   **CCU 同步等待**：最多 3 次状态检查
    

## 8\. 异常处理策略

### 8.1 下载异常

*   **网络断开**：重试机制
    
*   **服务器错误**：记录错误并重试
    
*   **磁盘空间不足**：立即失败并上报
    

### 8.2 校验异常

*   **MD5 不匹配**：删除下载文件，标记失败
    
*   **文件损坏**：同上
    

### 8.3 安装异常

*   **解压失败**：回滚到原版本
    
*   **文件替换失败**：保持原版本运行
    

### 8.4 重启异常

*   **重启失败**：系统 watchdog 触发安全重启
    
*   **启动失败**：启动脚本检测并回滚
    

## 9\. 测试建议

### 9.1 单元测试

*   MD5 校验函数测试
    
*   状态机转换测试
    
*   事件上报测试
    

### 9.2 集成测试

*   完整升级流程测试
    
*   网络异常测试
    
*   断电重启测试
    

### 9.3 压力测试

*   大文件下载测试
    
*   并发升级测试
    
*   长时间运行稳定性测试
    

## 10\. 维护建议

1.  **定期检查升级日志**：监控升级成功率
    
2.  **升级包版本管理**：确保云端只下发兼容版本
    
3.  **回滚机制完善**：准备手动回滚方案
    
4.  **监控升级状态**：实时监控设备升级进度
    
5.  **安全加固**：验证升级包来源和完整性
    

* * *

本文档基于项目源码分析编写，涵盖了 OTA 升级功能的核心技术实现。如有更新或需要补充特定细节，请参考相关源码文件。
