# MCU 升级失败根因分析报告

## 现象

在 CAN 总线正常的环境下运行 `qsjnic_test --upgrade-mcu`，完整日志见 `/Users/admin/workspace/jyq/doc/logs_from_device/ota_run.log`。

## 升级流程分步结果

| 步骤 | 命令 | MCU 响应 | 耗时 |
|------|------|---------|------|
| 建链 | Setup(0x01) | ✅ SetupAck(0x03) | 11ms |
| Public Warmup | 0x81/0x86/0x84/0x88/0x8A/0x82/0x83 | ✅ 全部通过 | 3.5s |
| 请求升级 | 0x80 UPDATE_REQ | ✅ 链路 ACK + 应用层 ACK | 5s |
| 开始升级 | 0x81 UPDATE_BEGIN | ✅ UPDATE_LEN=1024 + IND_AQUIRE idx=0 | 2.6s |
| **发数据** | **0x82 UPDATE_DATA idx=0 (1035 bytes)** | **❌ 无响应** | **超时** |
| 重试 | 0x82 (第二次) | ❌ 仍然无响应 | 超时 |
| 放弃 | - | - | - |

## 关键证据

**0x82 数据帧发送成功后，MCU 在 2ms 后还发了一个 Heartbeat：**

```
[19:04:40.603] TX [Upgrade: DATA idx=0] len=1035
[19:04:42.945] RX [Frame] len=7, hex: FF AA 00 07 13 05 E0
                                       序列号 0x13 ↑  Heartbeat 0x05 ↑
```

这说明：
1. **UART 硬件正常工作** ✅（能收到 Heartbeat）
2. **链路层没有断开** ✅（序列号在递增）
3. **MCU 协议解析器处理了心跳** ✅
4. **但 MCU_UPGRADE 模块丢弃了 0x82 数据帧** ❌

## 根因定位：MCU 固件消息队列未正确初始化

从 MCU 固件 (`mcu_app.bin`) 提取的 `MCU_UPGRADE` 模块错误字符串：

```
MCU_UPGRADE
[33mW(%010d) %s,%s:
[39mgMcuUpgradeMsgQueue is NULL!
```

| 错误 | 含义 |
|------|------|
| `gMcuUpgradeMsgQueue is NULL!` | 升级消息队列为 NULL |
| `recv data list is full` | 接收数据列表已满 |
| `malloc recv data failed` | 内存分配失败 |
| `index[%d] error` | 索引校验失败 |
| `proc_mcu_data,type=%02x` | 数据分发函数 |

当 0x81 (UPDATE_BEGIN) 到达时，MCU 创建 `MCU_UPGRADE` 任务和消息队列。如果队列创建失败（**很可能是 FreeRTOS 堆内存不足**），`gMcuUpgradeMsgQueue` 保持 NULL，后续所有 0x82 数据帧在 `proc_mcu_data` 函数中被直接丢弃。

## 证据链

```
0x81 到达 → MCU 创建队列 → xQueueCreate 失败 → gMcuUpgradeMsgQueue = NULL
                                                          ↓
0x82 到达 → proc_mcu_data() → 检查 gMcuUpgradeMsgQueue → 是 NULL → 丢弃帧
```

**MCU 日志应该有对应的 `gMcuUpgradeMsgQueue is NULL!` 输出**，但 ARM 侧日志看不到 MCU 内部日志——需要用 J-Link 在 MCU 内部设断点确认。

## 结论

**Bug 在 MCU 固件：MCU_UPGRADE 模块在 0x81 处理时创建的消息队列失败，导致所有 0x82 数据帧被丢弃。**

## 修复建议（给 MCU 固件开发者）

1. 在 0x81 处理函数中检查 `xQueueCreate` 返回值
2. 如果创建失败，增大 FreeRTOS 堆大小 (`configTOTAL_HEAP_SIZE`)
3. 或者延迟队列创建时机，在 0x80 处理时提前创建

## 附录：复现方法

```bash
# 需 CAN 总线环境
adb shell su root /data/local/tmp/qsjnic_test /dev/ttyS7 --upgrade-mcu --bin /data/local/tmp/mcu_app.bin
```
