The file /Users/admin/workspace/jyq/qsjnic/docs/MCU_ARM_Reference/20260513/方控按键测试报告_20260529.md has been updated successfully. (file state is current in your context — no need to Read it back)

# 方控按键 M2A 通信测试报告

## 基本信息

| 项目 | 内容 |
|------|------|
| 日期 | 2026-05-29 |
| 项目 | QSJNIC 车载 Android 中间件 |
| 版本 | v1.0.0-beta6 |
| MCU 固件 | swVersion=0302_20260527 |
| MCU 硬件 | hwVersion=PAJERO69XZA0120018 |
| 测试设备 | 车机 192.168.0.66 |
| 协议文档 | `docs/MCU_ARM_Reference/Key.xlsx` → "其它项目" 映射表 |
| MCU 方控自测文档 | `docs/MCU_ARM_Reference/1.方控和车速自测.txt` |
| 串口工具 | minicom (Linux/macOS), Xshell (Windows) |

---

## 一、测试前提

Android 中间件服务 (`com.qsjnic.mcu.service`) 必须与 MCU 建链成功。

---

## 二、实物测试（方控板接线）

### 2.1 接线方式

- 方控板 KEY 线 → 车机尾线 SWC_L
- 方控板 GND 线  → 车机尾线 GND

### 2.2 MCU 端日志

每次按下方控按键，MCU 串口打印如下格式日志：

```
I(0000025683) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[TRIGGER]
[ARM_CORE,write data:] ff,aa,00,0b,08,06,02,01,04,01,de
I(0000026043) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[IDLE]
[ARM_CORE,write data:] ff,aa,00,0b,09,06,02,01,04,00,de
```

### 2.3 串口帧结构解析

以 `ff,aa,00,0b,08,06,02,01,04,01,de` 为例：

| 字节 | 值 | 含义 |
|------|-----|------|
| H0-H1 | ff aa | 帧头 |
| L0-L1 | 00 0b | 帧长度 = 11 字节 |
| Seq | 08 | 序列号 |
| Type | 06 | 帧类型 |
| MsgType | **02** | KEY 域 |
| Cmd | **01** | M2A_KEY (MCU→ARM) |
| P0 | **04** | KeyValue (body[0]) |
| P1 | **01** | KeyStatus (body[1]) |
| CS | de | 校验和 |

### 2.4 Android 端日志

MCU 帧到达 ARM 后，FrameRouter 打印：

```
I/FrameRouter: KEY value=0x04 status=0x01
```

---

## 三、模拟测试（minicom 串口命令）

在不接实物方控板时，通过 USB 转串口模块连接 MCU 调试串口，使用 minicom 直接注入按键帧。

### 3.1 minicom 连接 MCU

```bash
# 安装 minicom (macOS)
brew install minicom

# 安装 minicom (Linux)
sudo apt install minicom

# 连接 MCU 串口（根据实际设备名调整 /dev/ttyUSB0）
minicom -D /dev/ttyUSB0 -b 115200
```

波特率及其他串口参数以 MCU 固件实际配置为准。连接成功后出现 MCU Shell 提示符 `xiexw:/$`。

### 3.2 KeyTest 命令格式

在 minicom 终端中直接输入：

```
KeyTest <测试项> <按键值> <按键状态>
```

| 参数 | 说明 | 示例 |
|------|------|------|
| 测试项 | 固定为 `1`（M2A 按键测试） | 1 |
| 按键值 | 帕杰罗 KeyValue（0x00-0x25） | 0x19 |
| 按键状态 | 0x01=按下(TRIGGER), 0x00=弹起(IDLE) | 0x01 |

### 3.3 单键示例（挂断键）

在 minicom 中依次输入按下和弹起：

```
xiexw:/$ KeyTest 1 0x19 0x01
I(0000490647) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x01
[ARM_CORE,write data:] ff,aa,00,0b,1c,06,02,01,19,01,b5

xiexw:/$ KeyTest 1 0x19 0x00
I(0000535107) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x00
[ARM_CORE,write data:] ff,aa,00,0b,1d,06,02,01,19,00,b5
```

MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端可从 FrameRouter 日志确认接收。

### 3.4 全部 9 个帕杰罗按键 minicom 命令

以下命令直接复制到 minicom 终端逐行执行：

```
# 语音 (0x03)
KeyTest 1 0x03 0x01
KeyTest 1 0x03 0x00

# 音乐 (0x04)
KeyTest 1 0x04 0x01
KeyTest 1 0x04 0x00

# 音量- (0x08)
KeyTest 1 0x08 0x01
KeyTest 1 0x08 0x00

# 音量+ (0x09)
KeyTest 1 0x09 0x01
KeyTest 1 0x09 0x00

# 上一曲 (0x0E)
KeyTest 1 0x0E 0x01
KeyTest 1 0x0E 0x00

# 下一曲 (0x0F)
KeyTest 1 0x0F 0x01
KeyTest 1 0x0F 0x00

# 接听 (0x18)
KeyTest 1 0x18 0x01
KeyTest 1 0x18 0x00

# 挂断 (0x19)
KeyTest 1 0x19 0x01
KeyTest 1 0x19 0x00

# 摄像头 (0x25)
KeyTest 1 0x25 0x01
KeyTest 1 0x25 0x00
```

### 3.5 同时监控 Android 端日志

另开一个终端，通过 ADB 实时查看 Android 端接收情况：

```bash
adb -s 192.168.0.66:5555 logcat -v time | grep --line-buffered "KEY value="
```

每执行一条 KeyTest 命令，Android 端应打印对应的 KEY value 日志。

---

## 四、帕杰罗方控按键值定义

MCU 固件侧枚举（`docs/MCU_ARM_Reference/1.方控和车速自测.txt`）：

```c
typedef enum
{
    EN_KEYMGR_SWC_TYPE_IDLE             = 0x00,//空闲
    EN_KEYMGR_SWC_TYPE_VOLUME_DOWN      = 0x08,//音量减
    EN_KEYMGR_SWC_TYPE_VOLUME_UP        = 0x09,//音量加
    EN_KEYMGR_SWC_TYPE_NEXT             = 0x0F,//下一曲
    EN_KEYMGR_SWC_TYPE_PREV             = 0x0E,//上一曲
    EN_KEYMGR_SWC_TYPE_MUSIC            = 0x04,//音乐
    EN_KEYMGR_SWC_TYPE_SPEECH           = 0x03,//语音
    EN_KEYMGR_SWC_TYPE_ANSWER           = 0x18,//接听
    EN_KEYMGR_SWC_TYPE_REJECT           = 0x19,//挂断
    EN_KEYMGR_SWC_TYPE_CAMERA           = 0x25,//摄像头
} EN_KEYMGR_SWC_TYPE;
```

对应 Key.xlsx "其它项目" 映射表（行 44-73）。

---

## 五、Android 端 M2A 实测结果

所有 9 种按键均通过物理方控板 + minicom KeyTest 双路径触发，Android 端 FrameRouter 完整捕获。

| 按键值 | 帕杰罗功能 | MC3范围内? | 接收次数 | 状态 |
|--------|-----------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | ✓ | 2 | 正常 |
| 0x04 | KEY_MUSIC 音乐 | ✓ | 3 | 正常 |
| 0x08 | KEY_VOL_DEC 音量- | ✓ | 2 | 正常 |
| 0x09 | KEY_VOL_INC 音量+ | ✓ | 2 | 正常 |
| 0x0E | KEY_PREV 上一曲 | ✗ 扩展值 | 3 | 正常 |
| 0x0F | KEY_NEXT 下一曲 | ✗ 扩展值 | 2 | 正常 |
| 0x18 | KEY_ANSWER 接听 | ✗ 扩展值 | 1 | 正常 |
| 0x19 | KEY_REJECT 挂断 | ✗ 扩展值 | 1 | 正常 |
| 0x25 | KEY_CAMERA 摄像头 | ✗ 扩展值 | 1 | 正常 |

### Android 端日志示例

```
I/FrameRouter: KEY value=0x04 status=0x01    ← 音乐键按下
I/FrameRouter: KEY value=0x04 status=0x00    ← 音乐键弹起
I/FrameRouter: KEY value=0x0E status=0x01    ← 上一曲按下
I/FrameRouter: KEY value=0x0E status=0x00    ← 上一曲弹起
I/FrameRouter: KEY value=0x0F status=0x01    ← 下一曲按下
I/FrameRouter: KEY value=0x0F status=0x00    ← 下一曲弹起
I/FrameRouter: KEY value=0x09 status=0x01    ← 音量+按下
I/FrameRouter: KEY value=0x08 status=0x01    ← 音量-按下
I/FrameRouter: KEY value=0x03 status=0x01    ← 语音键按下
I/FrameRouter: KEY value=0x18 status=0x01    ← 接听键按下
I/FrameRouter: KEY value=0x19 status=0x01    ← 挂断键按下
I/FrameRouter: KEY value=0x25 status=0x01    ← 摄像头键按下
```

---

## 六、Android 端 M2A 接收链路确认

```
MCU 串口 TX
    ↓
C 协议层 (mcu_protocol.c) — 帧解码
    ↓
JNI (jni_bridge.cpp) — body 字节提取
    ↓
FrameRouter.dispatch() — msgType=0x02 路由
    ↓
FrameRouter.handleKey() — cmd=0x01, 无 keyValue 范围校验
    ↓
KeyFeature.onFrame() — 透传至 Decoders
    ↓
Decoders.parseKeyControl() — 仅校验 body.length >= 2
    ↓
broadcastKeyEvent(keyValue, keyStatus) — 广播至所有监听者
    ↓
Vehicle Demo App (IMcuKeyListener.onKeyEvent)
```

**全链路无任何 keyValue 范围过滤。MCU 上报的任何值（0x00-0x25）均可完整到达应用层。**

---

## 七、结论

1. **M2A 方向**：9 种帕杰罗方控按键全部正常接收，含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），按下和弹起事件完整
2. **串口协议**：帧结构（ff aa + len + seq + type + msgType=02 + cmd=01 + keyValue + keyStatus + cs）一致
3. **SDK 已修复**：McuKeyClient 常量已从 MC3 切换为帕杰罗映射，Commands.Key.key() 校验范围已放宽至 0x25，Vehicle Demo 按钮已对齐帕杰罗值
4. **A2M 方向**：MCU 固件 `0302_20260527` 未注册 `MSG_TYPE_KEY` 的 A2M 处理函数（`msgType[2] not register proc fn`），A2M KEY 暂时不可用，待 MCU 固件更新

---

## 八、A2M 按键发送现状

Android 端通过 Vehicle Demo 发送 A2M 按键时：

- 传输层正常：MCU 收到帧并回 ACK（Android 拿到有效 seq）
- 应用层未实现：MCU 打印 `E: msgType[2] not register proc fn`
- 自测文档写明：`KEY_A2M_KEY暂时不用实现`

A2M 方向需等待 MCU 固件注册 `MSG_TYPE_KEY` 的接收处理函数后可用。

---

## 九、参考文档

| 文档 | 路径 |
|------|------|
| Key 协议 (MC3 + 其它项目映射) | `docs/MCU_ARM_Reference/Key.xlsx` |
| 方控和车速自测 (MCU 侧) | `docs/MCU_ARM_Reference/1.方控和车速自测.txt` |
| MCU-ARM 接口清单 | `docs/MCU_ARM_Reference/20260513/MCU_ARM_接口文档清单与明细_20260513.md` |
| 全链路测试报告 | `imgs/full_test_report.md` |
| SDK Key 常量 (已更新为帕杰罗) | `sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java` |
| Key 编码校验 (已放宽至 0x25) | `contract/src/main/java/com/qsjnic/mcu/domain/Commands.java` |
| Vehicle Demo (帕杰罗映射) | `demos/vehicle-demo/app/src/main/java/com/qsjnic/demo/vehicle/MainActivity.java` |

---

Android 中间件测试组
2026-05-29

-| 测试工具 | Xshell (https://www.xshell.com/zh/xshell/) |

+| 串口工具 | minicom (Linux/macOS), Xshell (Windows) |

-## 三、模拟测试（Shell/串口命令）

+## 三、模拟测试（minicom 串口命令）

-在不接实物方控板时，可通过 MCU 串口 Shell 直接注入按键帧。

+在不接实物方控板时，通过 USB 转串口模块连接 MCU 调试串口，使用 minicom 直接注入按键帧。

+波特率及其他串口参数以 MCU 固件实际配置为准。连接成功后出现 MCU Shell 提示符 `xiexw:/$`。

+在 minicom 终端中直接输入：

+### 3.3 单键示例（挂断键）

+在 minicom 中依次输入按下和弹起：

-### 3.3 全部 9 个帕杰罗按键模拟命令

+MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端可从 FrameRouter 日志确认接收。

+以下命令直接复制到 minicom 终端逐行执行：

+另开一个终端，通过 ADB 实时查看 Android 端接收情况：

+adb -s 192.168.0.66:5555 logcat -v time | grep --line-buffered "KEY value="

+每执行一条 KeyTest 命令，Android 端应打印对应的 KEY value 日志。

## 四、帕杰罗方控按键值定义

-所有 9 种按键均通过物理方控板触发，Android 端 FrameRouter 完整捕获。

+所有 9 种按键均通过物理方控板 + minicom KeyTest 双路径触发，Android 端 FrameRouter 完整捕获。

| 按键值 | 帕杰罗功能 | MC3范围内? | 接收次数 | 状态 |

-3. **已知问题**：SDK 常量使用 MC3 映射表，与帕杰罗映射值语义不同，需后续对齐

-4. **A2M 方向**：自测文档明确 "KEY_A2M_KEY 暂时不用实现"，当前无业务影响

+3. **SDK 已修复**：McuKeyClient 常量已从 MC3 切换为帕杰罗映射，Commands.Key.key() 校验范围已放宽至 0x25，Vehicle Demo 按钮已对齐帕杰罗值

+4. **A2M 方向**：MCU 固件 `0302_20260527` 未注册 `MSG_TYPE_KEY` 的 A2M 处理函数（`msgType[2] not register proc fn`），A2M KEY 暂时不可用，待 MCU 固件更新

+## 八、A2M 按键发送现状

+- 传输层正常：MCU 收到帧并回 ACK（Android 拿到有效 seq）

+- 应用层未实现：MCU 打印 `E: msgType[2] not register proc fn`

+A2M 方向需等待 MCU 固件注册 `MSG_TYPE_KEY` 的接收处理函数后可用。

-| SDK Key 常量 | `sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java` |

-| Key 编码校验 | `contract/src/main/java/com/qsjnic/mcu/domain/Commands.java` |

+| SDK Key 常量 (已更新为帕杰罗) | `sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java` |

+| Key 编码校验 (已放宽至 0x25) | `contract/src/main/java/com/qsjnic/mcu/domain/Commands.java` |

+| Vehicle Demo (帕杰罗映射) | `demos/vehicle-demo/app/src/main/java/com/qsjnic/demo/vehicle/MainActivity.java` |

# 方控按键 M2A 通信测试报告

## 基本信息

| 项目 | 内容 |
|------|------|
| 日期 | 2026-05-29 |
| 项目 | QSJNIC 车载 Android 中间件 |
| 版本 | v1.0.0-beta6 |
| MCU 固件 | swVersion=0302_20260527 |
| MCU 硬件 | hwVersion=PAJERO69XZA0120018 |
| 测试设备 | 车机 192.168.0.66 |
| 协议文档 | `docs/MCU_ARM_Reference/Key.xlsx` → "其它项目" 映射表 |
| MCU 方控自测文档 | `docs/MCU_ARM_Reference/1.方控和车速自测.txt` |
| 测试工具 | Xshell (https://www.xshell.com/zh/xshell/) |

---

## 一、测试前提

Android 中间件服务 (`com.qsjnic.mcu.service`) 必须与 MCU 建链成功。

---

## 二、实物测试（方控板接线）

### 2.1 接线方式

- 方控板 KEY 线 → 车机尾线 SWC_L
- 方控板 GND 线  → 车机尾线 GND

### 2.2 MCU 端日志

每次按下方控按键，MCU 串口打印如下格式日志：

```
I(0000025683) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[TRIGGER]
[ARM_CORE,write data:] ff,aa,00,0b,08,06,02,01,04,01,de
I(0000026043) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[IDLE]
[ARM_CORE,write data:] ff,aa,00,0b,09,06,02,01,04,00,de
```

### 2.3 串口帧结构解析

以 `ff,aa,00,0b,08,06,02,01,04,01,de` 为例：

| 字节 | 值 | 含义 |
|------|-----|------|
| H0-H1 | ff aa | 帧头 |
| L0-L1 | 00 0b | 帧长度 = 11 字节 |
| Seq | 08 | 序列号 |
| Type | 06 | 帧类型 |
| MsgType | **02** | KEY 域 |
| Cmd | **01** | M2A_KEY (MCU→ARM) |
| P0 | **04** | KeyValue (body[0]) |
| P1 | **01** | KeyStatus (body[1]) |
| CS | de | 校验和 |

### 2.4 Android 端日志

MCU 帧到达 ARM 后，FrameRouter 打印：

```
I/FrameRouter: KEY value=0x04 status=0x01
```

---

## 三、模拟测试（Shell/串口命令）

在不接实物方控板时，可通过 MCU 串口 Shell 直接注入按键帧。

### 3.1 命令格式

```
KeyTest <测试项> <按键值> <按键状态>
```

| 参数 | 说明 | 示例 |
|------|------|------|
| 测试项 | 固定为 `1`（M2A 按键测试） | 1 |
| 按键值 | 帕杰罗 KeyValue（0x00-0x25） | 0x19 |
| 按键状态 | 0x01=按下(TRIGGER), 0x00=弹起(IDLE) | 0x01 |

### 3.2 示例

挂断键按下和弹起：

```
xiexw:/$ KeyTest 1 0x19 0x01
I(0000490647) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x01
[ARM_CORE,write data:] ff,aa,00,0b,1c,06,02,01,19,01,b5

xiexw:/$ KeyTest 1 0x19 0x00
I(0000535107) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x00
[ARM_CORE,write data:] ff,aa,00,0b,1d,06,02,01,19,00,b5
```

### 3.3 全部 9 个帕杰罗按键模拟命令

```
# 语音
KeyTest 1 0x03 0x01
KeyTest 1 0x03 0x00

# 音乐
KeyTest 1 0x04 0x01
KeyTest 1 0x04 0x00

# 音量-
KeyTest 1 0x08 0x01
KeyTest 1 0x08 0x00

# 音量+
KeyTest 1 0x09 0x01
KeyTest 1 0x09 0x00

# 上一曲
KeyTest 1 0x0E 0x01
KeyTest 1 0x0E 0x00

# 下一曲
KeyTest 1 0x0F 0x01
KeyTest 1 0x0F 0x00

# 接听
KeyTest 1 0x18 0x01
KeyTest 1 0x18 0x00

# 挂断
KeyTest 1 0x19 0x01
KeyTest 1 0x19 0x00

# 摄像头
KeyTest 1 0x25 0x01
KeyTest 1 0x25 0x00
```

---

## 四、帕杰罗方控按键值定义

MCU 固件侧枚举（`docs/MCU_ARM_Reference/1.方控和车速自测.txt`）：

```c
typedef enum
{
    EN_KEYMGR_SWC_TYPE_IDLE             = 0x00,//空闲
    EN_KEYMGR_SWC_TYPE_VOLUME_DOWN      = 0x08,//音量减
    EN_KEYMGR_SWC_TYPE_VOLUME_UP        = 0x09,//音量加
    EN_KEYMGR_SWC_TYPE_NEXT             = 0x0F,//下一曲
    EN_KEYMGR_SWC_TYPE_PREV             = 0x0E,//上一曲
    EN_KEYMGR_SWC_TYPE_MUSIC            = 0x04,//音乐
    EN_KEYMGR_SWC_TYPE_SPEECH           = 0x03,//语音
    EN_KEYMGR_SWC_TYPE_ANSWER           = 0x18,//接听
    EN_KEYMGR_SWC_TYPE_REJECT           = 0x19,//挂断
    EN_KEYMGR_SWC_TYPE_CAMERA           = 0x25,//摄像头
} EN_KEYMGR_SWC_TYPE;
```

对应 Key.xlsx "其它项目" 映射表（行 44-73）。

---

## 五、Android 端 M2A 实测结果

所有 9 种按键均通过物理方控板触发，Android 端 FrameRouter 完整捕获。

| 按键值 | 帕杰罗功能 | MC3范围内? | 接收次数 | 状态 |
|--------|-----------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | ✓ | 2 | 正常 |
| 0x04 | KEY_MUSIC 音乐 | ✓ | 3 | 正常 |
| 0x08 | KEY_VOL_DEC 音量- | ✓ | 2 | 正常 |
| 0x09 | KEY_VOL_INC 音量+ | ✓ | 2 | 正常 |
| 0x0E | KEY_PREV 上一曲 | ✗ 扩展值 | 3 | 正常 |
| 0x0F | KEY_NEXT 下一曲 | ✗ 扩展值 | 2 | 正常 |
| 0x18 | KEY_ANSWER 接听 | ✗ 扩展值 | 1 | 正常 |
| 0x19 | KEY_REJECT 挂断 | ✗ 扩展值 | 1 | 正常 |
| 0x25 | KEY_CAMERA 摄像头 | ✗ 扩展值 | 1 | 正常 |

### Android 端日志示例

```
I/FrameRouter: KEY value=0x04 status=0x01    ← 音乐键按下
I/FrameRouter: KEY value=0x04 status=0x00    ← 音乐键弹起
I/FrameRouter: KEY value=0x0E status=0x01    ← 上一曲按下
I/FrameRouter: KEY value=0x0E status=0x00    ← 上一曲弹起
I/FrameRouter: KEY value=0x0F status=0x01    ← 下一曲按下
I/FrameRouter: KEY value=0x0F status=0x00    ← 下一曲弹起
I/FrameRouter: KEY value=0x09 status=0x01    ← 音量+按下
I/FrameRouter: KEY value=0x08 status=0x01    ← 音量-按下
I/FrameRouter: KEY value=0x03 status=0x01    ← 语音键按下
I/FrameRouter: KEY value=0x18 status=0x01    ← 接听键按下
I/FrameRouter: KEY value=0x19 status=0x01    ← 挂断键按下
I/FrameRouter: KEY value=0x25 status=0x01    ← 摄像头键按下
```

---

## 六、Android 端 M2A 接收链路确认

```
MCU 串口 TX
    ↓
C 协议层 (mcu_protocol.c) — 帧解码
    ↓
JNI (jni_bridge.cpp) — body 字节提取
    ↓
FrameRouter.dispatch() — msgType=0x02 路由
    ↓
FrameRouter.handleKey() — cmd=0x01, 无 keyValue 范围校验
    ↓
KeyFeature.onFrame() — 透传至 Decoders
    ↓
Decoders.parseKeyControl() — 仅校验 body.length >= 2
    ↓
broadcastKeyEvent(keyValue, keyStatus) — 广播至所有监听者
    ↓
Vehicle Demo App (IMcuKeyListener.onKeyEvent)
```

**全链路无任何 keyValue 范围过滤。MCU 上报的任何值（0x00-0x25）均可完整到达应用层。**

---

## 七、结论

1. **M2A 方向**：9 种帕杰罗方控按键全部正常接收，含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），按下和弹起事件完整
2. **串口协议**：帧结构（ff aa + len + seq + type + msgType=02 + cmd=01 + keyValue + keyStatus + cs）一致
3. **已知问题**：SDK 常量使用 MC3 映射表，与帕杰罗映射值语义不同，需后续对齐
4. **A2M 方向**：自测文档明确 "KEY_A2M_KEY 暂时不用实现"，当前无业务影响

---

## 八、参考文档

| 文档 | 路径 |
|------|------|
| Key 协议 (MC3 + 其它项目映射) | `docs/MCU_ARM_Reference/Key.xlsx` |
| 方控和车速自测 (MCU 侧) | `docs/MCU_ARM_Reference/1.方控和车速自测.txt` |
| MCU-ARM 接口清单 | `docs/MCU_ARM_Reference/20260513/MCU_ARM_接口文档清单与明细_20260513.md` |
| 全链路测试报告 | `imgs/full_test_report.md` |
| SDK Key 常量 | `sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java` |
| Key 编码校验 | `contract/src/main/java/com/qsjnic/mcu/domain/Commands.java` |

---

Android 中间件测试组
2026-05-29


更新文档，后来通过minicom命令测试的，minicom的命令行命令要列出来


Now let me also update the full_test_report.md to reflect the SDK fix.


文档已更新，新增内容：

- **minicom 安装和连接命令**（macOS/Linux）
- **minicom 终端中逐行执行的 KeyTest 命令**
- **ADB 实时监控命令**（配合 minicom 双终端观察）
- **A2M 现状** 单独章节说明 MCU `not register proc fn` 问题
- **结论 #3** 更新为 SDK 已修复，参考文档表补充到 7 条

顺手把 `imgs/full_test_report.md` 里面 Key 域的部分也同步更新？


好的


Let me read the full test report and update the Key domain section to reflect the SDK fix.


111	---
112
113	## 四、Key 域 — 协议一致，存在按键映射不匹配
114
115	### 4.1 M2A（MCU→ARM）
116
117	未触发（需物理方控按键），但代码路径验证通过。
118
119	### 4.2 A2M（ARM→MCU）测试结果
120
121	通过 Vehicle Demo App 触发：
122
123	| 按键 | keyValue | keyStatus | seq | 状态 |
124	|------|----------|-----------|-----|------|
125	| MODE | 0x01 | 0x01（短按） | 23 | ✓ |
126	| 音量+ | 0x0A | 0x01（短按） | 24 | ✓ |
127	| 音量- | 0x0B | 0x01（短按） | 25 | ✓ |
128
129	`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK。
130
131	### 4.3 协议一致性
132
133	| 项目 | 协议 Key.xlsx | 代码 | 结果 |
134	|------|-------------|------|------|
135	| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
136	| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
137	| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
138	| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
139	| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |
140
141	### 4.4 按键值映射不匹配
142
143	Key.xlsx 定义了四套按键映射表，SDK 使用了 MC3 映射，但帕杰罗车机实际使用"其它项目"映射：
144
145	| 功能 | SDK 常量 (MC3) | 帕杰罗实际值 (其它项目) |
146	|------|---------------|----------------------|
147	| 音量- | 0x0B | 0x08 |
148	| 音量+ | 0x0A | 0x09 |
149	| 上一曲 | 0x08 | 0x0E |
150	| 下一曲 | 0x09 | 0x0F |
151	| 接听 | 未定义 | 0x18 |
152	| 挂断 | 未定义 | 0x19 |
153	| 摄像头 | 未定义 | 0x25 |
154
155	此外 `Commands.Key.key()` 校验范围为 `0x00-0x0B`，帕杰罗的扩展值（0x0E-0x25）会触发异常。
156
157	### 4.5 结论
158
159	**Key 域协议帧结构正确。但 SDK 按键常量使用 MC3 映射表，与帕杰罗车型的"其它项目"映射表不匹配。由于当前 A2M Key 暂不使用（自测文档明确"KEY_A2M_KEY暂时不用实现"），实际功能不受影响。**
160
161	---
162
163	## 五、软件层全局审计结论
164
165	对全部 7 层软件链路进行了逐模块审计：
166
167	| 层级 | 文件 | 检查结果 |
168	|------|------|---------|
169	| C 协议 | `mcu_protocol.c` | 帧编解码正确 |
170	| C 传输 | `mcu_transport.c` | 串口 I/O、回调链正确 |
171	| JNI | `jni_bridge.cpp` | body 字节传递正确 |
172	| Java 分发 | `FrameRouter.java` | msgType/cmd 路由正确 |
173	| Java 业务 | `VehicleFeature.java` | Public 26 个 M2A cmd 映射正确 |
174	| Java 业务 | `RadioFeature.java` | Radio 5 个 M2A cmd 映射正确 |
175	| Java 业务 | `KeyFeature.java` | Key 1 个 M2A cmd 映射正确 |

---

## 四、Key 域 — 协议一致，存在按键映射不匹配

### 4.1 M2A（MCU→ARM）

未触发（需物理方控按键），但代码路径验证通过。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue | keyStatus | seq | 状态 |
|------|----------|-----------|-----|------|
| MODE | 0x01 | 0x01（短按） | 23 | ✓ |
| 音量+ | 0x0A | 0x01（短按） | 24 | ✓ |
| 音量- | 0x0B | 0x01（短按） | 25 | ✓ |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射不匹配

Key.xlsx 定义了四套按键映射表，SDK 使用了 MC3 映射，但帕杰罗车机实际使用"其它项目"映射：

| 功能 | SDK 常量 (MC3) | 帕杰罗实际值 (其它项目) |
|------|---------------|----------------------|
| 音量- | 0x0B | 0x08 |
| 音量+ | 0x0A | 0x09 |
| 上一曲 | 0x08 | 0x0E |
| 下一曲 | 0x09 | 0x0F |
| 接听 | 未定义 | 0x18 |
| 挂断 | 未定义 | 0x19 |
| 摄像头 | 未定义 | 0x25 |

此外 `Commands.Key.key()` 校验范围为 `0x00-0x0B`，帕杰罗的扩展值（0x0E-0x25）会触发异常。

### 4.5 结论

**Key 域协议帧结构正确。但 SDK 按键常量使用 MC3 映射表，与帕杰罗车型的"其它项目"映射表不匹配。由于当前 A2M Key 暂不使用（自测文档明确"KEY_A2M_KEY暂时不用实现"），实际功能不受影响。**

---

## 五、软件层全局审计结论

对全部 7 层软件链路进行了逐模块审计：

| 层级 | 文件 | 检查结果 |
|------|------|---------|
| C 协议 | `mcu_protocol.c` | 帧编解码正确 |
| C 传输 | `mcu_transport.c` | 串口 I/O、回调链正确 |
| JNI | `jni_bridge.cpp` | body 字节传递正确 |
| Java 分发 | `FrameRouter.java` | msgType/cmd 路由正确 |
| Java 业务 | `VehicleFeature.java` | Public 26 个 M2A cmd 映射正确 |
| Java 业务 | `RadioFeature.java` | Radio 5 个 M2A cmd 映射正确 |
| Java 业务 | `KeyFeature.java` | Key 1 个 M2A cmd 映射正确 |


Now I need to update sections 4.x in the full test report to reflect the current state:

1. 4.1 M2A - update to show the physical button + minicom KeyTest results, not "未触发"
2. 4.2 A2M - update to show the MCU `not register proc fn` discovery
3. 4.4 - update to show the mapping has been FIXED
4. 4.5 - update conclusion
5. Problem summary table #4 - update status


Edit

## 四、Key 域 — 协议一致，存在按键映射不匹配

### 4.1 M2A（MCU→ARM）

未触发（需物理方控按键），但代码路径验证通过。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue | keyStatus | seq | 状态 |
|------|----------|-----------|-----|------|
| MODE | 0x01 | 0x01（短按） | 23 | ✓ |
| 音量+ | 0x0A | 0x01（短按） | 24 | ✓ |
| 音量- | 0x0B | 0x01（短按） | 25 | ✓ |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射不匹配

Key.xlsx 定义了四套按键映射表，SDK 使用了 MC3 映射，但帕杰罗车机实际使用"其它项目"映射：

| 功能 | SDK 常量 (MC3) | 帕杰罗实际值 (其它项目) |
|------|---------------|----------------------|
| 音量- | 0x0B | 0x08 |
| 音量+ | 0x0A | 0x09 |
| 上一曲 | 0x08 | 0x0E |
| 下一曲 | 0x09 | 0x0F |
| 接听 | 未定义 | 0x18 |
| 挂断 | 未定义 | 0x19 |
| 摄像头 | 未定义 | 0x25 |

此外 `Commands.Key.key()` 校验范围为 `0x00-0x0B`，帕杰罗的扩展值（0x0E-0x25）会触发异常。

### 4.5 结论

**Key 域协议帧结构正确。但 SDK 按键常量使用 MC3 映射表，与帕杰罗车型的"其它项目"映射表不匹配。由于当前 A2M Key 暂不使用（自测文档明确"KEY_A2M_KEY暂时不用实现"），实际功能不受影响。**

## 四、Key 域 — 已修复，SDK 切换至帕杰罗映射

### 4.1 M2A（MCU→ARM）测试结果

通过物理方控板 + minicom KeyTest 双路径触发：

**物理方控：**

| 按键值 | 帕杰罗功能 | 接收次数 | 状态 |
|--------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | 2 | ✓ |
| 0x04 | KEY_MUSIC 音乐 | 3 | ✓ |
| 0x08 | KEY_VOL_DEC 音量- | 2 | ✓ |
| 0x09 | KEY_VOL_INC 音量+ | 2 | ✓ |
| 0x0E | KEY_PREV 上一曲 | 3 | ✓ |
| 0x0F | KEY_NEXT 下一曲 | 2 | ✓ |
| 0x18 | KEY_ANSWER 接听 | 1 | ✓ |
| 0x19 | KEY_REJECT 挂断 | 1 | ✓ |
| 0x25 | KEY_CAMERA 摄像头 | 1 | ✓ |

含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），M2A 全链路无任何 keyValue 范围过滤，所有值正常接收。

**minicom 模拟：**

```bash
minicom -D /dev/ttyUSB0 -b 115200
xiexw:/$ KeyTest 1 0x19 0x01   # 按下挂断
xiexw:/$ KeyTest 1 0x19 0x00   # 弹起挂断
```

MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端 FrameRouter 同步打印 `KEY value=0x19 status=0x01`。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue (帕杰罗) | keyStatus | seq | 状态 |
|------|-------------------|-----------|-----|------|
| MODE | 0x0D | 0x01（短按） | - | 传输层 OK |
| MUTE | 0x0C | 0x01（短按） | - | 传输层 OK |
| 音量- | 0x08 | 0x01（短按） | 163 | 传输层 OK |
| 音量+ | 0x09 | 0x01（短按） | 162 | 传输层 OK |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK（传输层正常）。但 MCU 同时打印：

```
E: ARMCORE,mcucomm_notify_recv_data:msgType[2] not register proc fn
```

MCU 传输层正确处理了帧（返回 ACK），但应用层未注册 `MSG_TYPE_KEY` 的 A2M 接收处理函数，数据被丢弃。这与自测文档"KEY_A2M_KEY暂时不用实现"一致。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射修复

Key.xlsx 中帕杰罗使用"其它项目"映射表（行 44-73），原 SDK 使用 MC3 映射。已修复：

| 功能 | 修复前 (MC3) | 修复后 (帕杰罗) |
|------|-------------|---------------|
| 音量- | 0x0B | **0x08** |
| 音量+ | 0x0A | **0x09** |
| 上一曲 | 0x08 | **0x0E** |
| 下一曲 | 0x09 | **0x0F** |
| 接听 | 未定义 | **0x18** |
| 挂断 | 未定义 | **0x19** |
| 摄像头 | 未定义 | **0x25** |
| MODE | 0x01 | **0x0D** |
| MUTE | 0x02 | **0x0C** |

修复文件：

| 文件 | 改动 |
|------|------|
| `sdk/.../McuKeyClient.java` | MC3 常量 → 帕杰罗常量 |
| `contract/.../Commands.java` | 校验上限 0x0B → 0x25 |
| `demos/.../MainActivity.java` | 按钮值 + swcName 对齐帕杰罗 |

### 4.5 结论

**Key 域 M2A 方向：9 种按键全部正常接收，含 5 个扩展值。SDK 常量已从 MC3 切换至帕杰罗映射，Demo 按钮已对齐。A2M 方向：MCU 固件未实现，待 MCU 侧注册 `MSG_TYPE_KEY` 处理函数。**


The file /Users/admin/workspace/jyq/imgs/full_test_report.md has been updated successfully. (file state is current in your context — no need to Read it back)

## 四、Key 域 — 已修复，SDK 切换至帕杰罗映射

### 4.1 M2A（MCU→ARM）测试结果

通过物理方控板 + minicom KeyTest 双路径触发：

**物理方控：**

| 按键值 | 帕杰罗功能 | 接收次数 | 状态 |
|--------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | 2 | ✓ |
| 0x04 | KEY_MUSIC 音乐 | 3 | ✓ |
| 0x08 | KEY_VOL_DEC 音量- | 2 | ✓ |
| 0x09 | KEY_VOL_INC 音量+ | 2 | ✓ |
| 0x0E | KEY_PREV 上一曲 | 3 | ✓ |
| 0x0F | KEY_NEXT 下一曲 | 2 | ✓ |
| 0x18 | KEY_ANSWER 接听 | 1 | ✓ |
| 0x19 | KEY_REJECT 挂断 | 1 | ✓ |
| 0x25 | KEY_CAMERA 摄像头 | 1 | ✓ |

含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），M2A 全链路无任何 keyValue 范围过滤，所有值正常接收。

**minicom 模拟：**

```bash
minicom -D /dev/ttyUSB0 -b 115200
xiexw:/$ KeyTest 1 0x19 0x01   # 按下挂断
xiexw:/$ KeyTest 1 0x19 0x00   # 弹起挂断
```

MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端 FrameRouter 同步打印 `KEY value=0x19 status=0x01`。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue (帕杰罗) | keyStatus | seq | 状态 |
|------|-------------------|-----------|-----|------|
| MODE | 0x0D | 0x01（短按） | - | 传输层 OK |
| MUTE | 0x0C | 0x01（短按） | - | 传输层 OK |
| 音量- | 0x08 | 0x01（短按） | 163 | 传输层 OK |
| 音量+ | 0x09 | 0x01（短按） | 162 | 传输层 OK |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK（传输层正常）。但 MCU 同时打印：

```
E: ARMCORE,mcucomm_notify_recv_data:msgType[2] not register proc fn
```

MCU 传输层正确处理了帧（返回 ACK），但应用层未注册 `MSG_TYPE_KEY` 的 A2M 接收处理函数，数据被丢弃。这与自测文档"KEY_A2M_KEY暂时不用实现"一致。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射修复

Key.xlsx 中帕杰罗使用"其它项目"映射表（行 44-73），原 SDK 使用 MC3 映射。已修复：

| 功能 | 修复前 (MC3) | 修复后 (帕杰罗) |
|------|-------------|---------------|
| 音量- | 0x0B | **0x08** |
| 音量+ | 0x0A | **0x09** |
| 上一曲 | 0x08 | **0x0E** |
| 下一曲 | 0x09 | **0x0F** |
| 接听 | 未定义 | **0x18** |
| 挂断 | 未定义 | **0x19** |
| 摄像头 | 未定义 | **0x25** |
| MODE | 0x01 | **0x0D** |
| MUTE | 0x02 | **0x0C** |

修复文件：

| 文件 | 改动 |
|------|------|
| `sdk/.../McuKeyClient.java` | MC3 常量 → 帕杰罗常量 |
| `contract/.../Commands.java` | 校验上限 0x0B → 0x25 |
| `demos/.../MainActivity.java` | 按钮值 + swcName 对齐帕杰罗 |

### 4.5 结论

**Key 域 M2A 方向：9 种按键全部正常接收，含 5 个扩展值。SDK 常量已从 MC3 切换至帕杰罗映射，Demo 按钮已对齐。A2M 方向：MCU 固件未实现，待 MCU 侧注册 `MSG_TYPE_KEY` 处理函数。**

# QSJNIC MCU 通信全链路测试报告

## 基本信息

| 项目 | 内容 |
|------|------|
| 日期 | 2026-05-28 |
| 项目 | QSJNIC 车载 Android 中间件 |
| 版本 | v1.0.0-beta6 |
| MCU 固件 | `swVersion=0302_20260527` |
| MCU 硬件 | `hwVersion=PAJERO69XZA0120018` |
| 测试设备 | 车机 192.168.0.66 |
| 协议文档 | `docs/MCU_ARM_Reference/20260513/` |

---

## 一、测试范围

对 Android 中间件与 MCU 之间的全部三个业务域进行了端到端测试：

| 域 | MsgType | 测试项 | M2A | A2M |
|----|---------|--------|-----|-----|
| Public（车辆信号） | 0x01 | LINE_DETECT, MCU_VERSION, TIME_INFO, SYS_STATUS, TFT_DUTY, 等 | 6 项 | 5 项 |
| Radio（收音机） | 0x05 | FREQ, PS_PTY, RT, SEEK | 3 项 | 1 项 |
| Key（方控按键） | 0x02 | KEY_M2A_KEY, KEY_A2M_KEY | 0 项 | 3 项 |

---

## 二、Radio 域 — MCU 固件缺陷（已证实）

### 2.1 发现

搜台后 `valid`、`signal` 始终为 0，`onPsPty` 和 `onRadioText` 回调无数据。

### 2.2 排查方法

在 `FrameRouter.handleRadio()` 中增加原始 hex dump，直接打印 MCU 发来的 body 字节，绕过所有软件解析层。

### 2.3 实测数据

**FREQ 帧（cmd=0x01）— 搜台中：**
```
FREQ_BODY[7]=26 B0 00 42 00 00 00 | Byte12=0x00 (valid=0) Byte14(signal)=0x00
```
- 频率 P0-P1: `26 B0` → `26 C4`（99.04→99.24 MHz）✓
- 波段 P2: `00`=FM ✓
- 搜台模式 P3: `42`=SEEK_FF+STEREO ✓
- **valid P4 Byte12: `0x00`（bit7=0）** ✗
- **PTY P5 Byte13: `0x00`** ✗
- **signal P6 Byte14: `0x00`** ✗

**PS_PTY 帧（cmd=0x02）：**
```
PS_PTY[9]=00 00 00 00 00 00 00 00 00 | PTY=0x00 PS="(empty)"
```
- 9 字节全部为零

**RT 帧（cmd=0x03）：**
```
RT[64]=00 00 00 ... 00 00 | RT="(empty)"
```
- 64 字节全部为零

### 2.4 软件层排查

| 层 | 检查项 | 结果 |
|----|-------|------|
| C 协议层 `mcu_protocol.c` | payload 从 `raw+6` 开始 | ✓ |
| JNI `jni_bridge.cpp` | `body = payload+2`, `body_len = payload_len-2` | ✓ |
| Java FrameRouter | payload 直接传递 | ✓ |
| DomainBus → RadioFeature | body 原样转发 | ✓ |
| RadioFeature | `valid = (p[4]>>7)&1`, `signal = p[6]&0xFF` | ✓ |
| Decoders.parsePsPty | `pty = body[0]`, `ps = trimUtf8(body, 1, 8)` | ✓ |
| AIDL → SDK → App | 回调传递 | ✓ |

### 2.5 结论

**MCU 固件 `0302_20260527` 的 Radio 域 M2A 帧（FREQ/PS_PTY/RT）结构正确但数据载荷全为零。这是 MCU 固件缺陷，不是 Android 端软件问题。**

---

## 三、Public 域 — 全部正常 ✓

### 3.1 M2A（MCU→ARM）测试结果

| cmd | 接口 | 实测值 | 状态 |
|-----|------|--------|------|
| 0x01 | LINE_DETECT | IG=0, ACC=1, Brake=0, Back=0, LTurn=1, RTurn=0 | ✓ |
| 0x02 | MCU_VERSION | "PAJERO69XZA0120018" | ✓ |
| 0x03 | TIME_INFO | 2025-01-01 01:42:08（未设置） | ✓ |
| 0x05 | SYS_STATUS | firstPwrOn=0 | ✓ |
| 0x08 | TFT_DUTY | 0% | ✓ |
| 0x13 | VERSION_STR | sw="0302_20260527", boot="03" | ✓ |

### 3.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| cmd | 操作 | 返回值 | 状态 |
|-----|------|--------|------|
| 0x82 | Mute ON | rc=0 | ✓ |
| 0x82 | Mute OFF | rc=0 | ✓ |
| 0x84 | Backlight 50% | rc=0 | ✓ |
| 0x84 | Backlight 100% | rc=0 | ✓ |
| 0x81 | Refresh Init | rc=0 | ✓ |

### 3.3 结论

**Public 域 M2A/A2M 双向通信全部正常。MCU 固件缺陷仅影响 Radio 域。**

---

## 四、Key 域 — 协议一致，存在按键映射不匹配

### 4.1 M2A（MCU→ARM）

未触发（需物理方控按键），但代码路径验证通过。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue | keyStatus | seq | 状态 |
|------|----------|-----------|-----|------|
| MODE | 0x01 | 0x01（短按） | 23 | ✓ |
| 音量+ | 0x0A | 0x01（短按） | 24 | ✓ |
| 音量- | 0x0B | 0x01（短按） | 25 | ✓ |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射不匹配

Key.xlsx 定义了四套按键映射表，SDK 使用了 MC3 映射，但帕杰罗车机实际使用"其它项目"映射：

| 功能 | SDK 常量 (MC3) | 帕杰罗实际值 (其它项目) |
|------|---------------|----------------------|
| 音量- | 0x0B | 0x08 |
| 音量+ | 0x0A | 0x09 |
| 上一曲 | 0x08 | 0x0E |
| 下一曲 | 0x09 | 0x0F |
| 接听 | 未定义 | 0x18 |
| 挂断 | 未定义 | 0x19 |
| 摄像头 | 未定义 | 0x25 |

此外 `Commands.Key.key()` 校验范围为 `0x00-0x0B`，帕杰罗的扩展值（0x0E-0x25）会触发异常。

### 4.5 结论

**Key 域协议帧结构正确。但 SDK 按键常量使用 MC3 映射表，与帕杰罗车型的"其它项目"映射表不匹配。由于当前 A2M Key 暂不使用（自测文档明确"KEY_A2M_KEY暂时不用实现"），实际功能不受影响。**

---

## 五、软件层全局审计结论

对全部 7 层软件链路进行了逐模块审计：

| 层级 | 文件 | 检查结果 |
|------|------|---------|
| C 协议 | `mcu_protocol.c` | 帧编解码正确 |
| C 传输 | `mcu_transport.c` | 串口 I/O、回调链正确 |
| JNI | `jni_bridge.cpp` | body 字节传递正确 |
| Java 分发 | `FrameRouter.java` | msgType/cmd 路由正确 |
| Java 业务 | `VehicleFeature.java` | Public 26 个 M2A cmd 映射正确 |
| Java 业务 | `RadioFeature.java` | Radio 5 个 M2A cmd 映射正确 |
| Java 业务 | `KeyFeature.java` | Key 1 个 M2A cmd 映射正确 |
| Java 解析 | `Decoders.java` | 全部解析器与协议一致 |
| Java 编码 | `Commands.java` | 全部编码器与协议一致 |
| Java 发送 | `McuLink.java` | 帧组装正确 |
| SDK | `McuClient.java` 等 | 回调转发正确 |

**Android 中间件软件层的 MCU 通信代码没有 bug。**

---

## 六、问题汇总

| 编号 | 问题 | 严重程度 | 责任方 | 状态 |
|------|------|---------|--------|------|
| #1 | Radio FREQ 帧 P4-P6 全部为零 | 高 | MCU 固件 | 待修复 |
| #2 | Radio PS_PTY 帧 9 字节全部为零 | 高 | MCU 固件 | 待修复 |
| #3 | Radio RT 帧 64 字节全部为零 | 高 | MCU 固件 | 待修复 |
| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | 待修复 |

---

## 七、建议

1. **紧急**：将 #1-#3 的 MCU 固件缺陷报告发给 MCU 供应商，要求修复 Radio 域数据填充
2. **后续**：修复 #4 的 Key 映射问题，在 SDK 中增加帕杰罗车型的按键常量
3. **后续**：将 `sendKeyEvent` 的日志补全（当前 `McuBinder` 和 `McuKeyClient` 无日志）

-## 四、Key 域 — 协议一致，存在按键映射不匹配

+## 四、Key 域 — 已修复，SDK 切换至帕杰罗映射

-未触发（需物理方控按键），但代码路径验证通过。

+| 按键值 | 帕杰罗功能 | 接收次数 | 状态 |

+含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），M2A 全链路无任何 keyValue 范围过滤，所有值正常接收。

+MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端 FrameRouter 同步打印 `KEY value=0x19 status=0x01`。

-| 按键 | keyValue | keyStatus | seq | 状态 |

+| 按键 | keyValue (帕杰罗) | keyStatus | seq | 状态 |

+| MODE | 0x0D | 0x01（短按） | - | 传输层 OK |

+| MUTE | 0x0C | 0x01（短按） | - | 传输层 OK |

-`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK。

+`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK（传输层正常）。但 MCU 同时打印：

+E: ARMCORE,mcucomm_notify_recv_data:msgType[2] not register proc fn

+MCU 传输层正确处理了帧（返回 ACK），但应用层未注册 `MSG_TYPE_KEY` 的 A2M 接收处理函数，数据被丢弃。这与自测文档"KEY_A2M_KEY暂时不用实现"一致。

-### 4.4 按键值映射不匹配

+### 4.4 按键值映射修复

-Key.xlsx 定义了四套按键映射表，SDK 使用了 MC3 映射，但帕杰罗车机实际使用"其它项目"映射：

+Key.xlsx 中帕杰罗使用"其它项目"映射表（行 44-73），原 SDK 使用 MC3 映射。已修复：

-此外 `Commands.Key.key()` 校验范围为 `0x00-0x0B`，帕杰罗的扩展值（0x0E-0x25）会触发异常。

+| 文件 | 改动 |

+| `sdk/.../McuKeyClient.java` | MC3 常量 → 帕杰罗常量 |

+| `contract/.../Commands.java` | 校验上限 0x0B → 0x25 |

+| `demos/.../MainActivity.java` | 按钮值 + swcName 对齐帕杰罗 |

-**Key 域协议帧结构正确。但 SDK 按键常量使用 MC3 映射表，与帕杰罗车型的"其它项目"映射表不匹配。由于当前 A2M Key 暂不使用（自测文档明确"KEY_A2M_KEY暂时不用实现"），实际功能不受影响。**

+**Key 域 M2A 方向：9 种按键全部正常接收，含 5 个扩展值。SDK 常量已从 MC3 切换至帕杰罗映射，Demo 按钮已对齐。A2M 方向：MCU 固件未实现，待 MCU 侧注册 `MSG_TYPE_KEY` 处理函数。**


Now update the problem summary table to reflect the fix status.


| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | 待修复 |

| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | **已修复** |


# QSJNIC MCU 通信全链路测试报告

## 基本信息

| 项目 | 内容 |
|------|------|
| 日期 | 2026-05-28 |
| 项目 | QSJNIC 车载 Android 中间件 |
| 版本 | v1.0.0-beta6 |
| MCU 固件 | `swVersion=0302_20260527` |
| MCU 硬件 | `hwVersion=PAJERO69XZA0120018` |
| 测试设备 | 车机 192.168.0.66 |
| 协议文档 | `docs/MCU_ARM_Reference/20260513/` |

---

## 一、测试范围

对 Android 中间件与 MCU 之间的全部三个业务域进行了端到端测试：

| 域 | MsgType | 测试项 | M2A | A2M |
|----|---------|--------|-----|-----|
| Public（车辆信号） | 0x01 | LINE_DETECT, MCU_VERSION, TIME_INFO, SYS_STATUS, TFT_DUTY, 等 | 6 项 | 5 项 |
| Radio（收音机） | 0x05 | FREQ, PS_PTY, RT, SEEK | 3 项 | 1 项 |
| Key（方控按键） | 0x02 | KEY_M2A_KEY, KEY_A2M_KEY | 0 项 | 3 项 |

---

## 二、Radio 域 — MCU 固件缺陷（已证实）

### 2.1 发现

搜台后 `valid`、`signal` 始终为 0，`onPsPty` 和 `onRadioText` 回调无数据。

### 2.2 排查方法

在 `FrameRouter.handleRadio()` 中增加原始 hex dump，直接打印 MCU 发来的 body 字节，绕过所有软件解析层。

### 2.3 实测数据

**FREQ 帧（cmd=0x01）— 搜台中：**
```
FREQ_BODY[7]=26 B0 00 42 00 00 00 | Byte12=0x00 (valid=0) Byte14(signal)=0x00
```
- 频率 P0-P1: `26 B0` → `26 C4`（99.04→99.24 MHz）✓
- 波段 P2: `00`=FM ✓
- 搜台模式 P3: `42`=SEEK_FF+STEREO ✓
- **valid P4 Byte12: `0x00`（bit7=0）** ✗
- **PTY P5 Byte13: `0x00`** ✗
- **signal P6 Byte14: `0x00`** ✗

**PS_PTY 帧（cmd=0x02）：**
```
PS_PTY[9]=00 00 00 00 00 00 00 00 00 | PTY=0x00 PS="(empty)"
```
- 9 字节全部为零

**RT 帧（cmd=0x03）：**
```
RT[64]=00 00 00 ... 00 00 | RT="(empty)"
```
- 64 字节全部为零

### 2.4 软件层排查

| 层 | 检查项 | 结果 |
|----|-------|------|
| C 协议层 `mcu_protocol.c` | payload 从 `raw+6` 开始 | ✓ |
| JNI `jni_bridge.cpp` | `body = payload+2`, `body_len = payload_len-2` | ✓ |
| Java FrameRouter | payload 直接传递 | ✓ |
| DomainBus → RadioFeature | body 原样转发 | ✓ |
| RadioFeature | `valid = (p[4]>>7)&1`, `signal = p[6]&0xFF` | ✓ |
| Decoders.parsePsPty | `pty = body[0]`, `ps = trimUtf8(body, 1, 8)` | ✓ |
| AIDL → SDK → App | 回调传递 | ✓ |

### 2.5 结论

**MCU 固件 `0302_20260527` 的 Radio 域 M2A 帧（FREQ/PS_PTY/RT）结构正确但数据载荷全为零。这是 MCU 固件缺陷，不是 Android 端软件问题。**

---

## 三、Public 域 — 全部正常 ✓

### 3.1 M2A（MCU→ARM）测试结果

| cmd | 接口 | 实测值 | 状态 |
|-----|------|--------|------|
| 0x01 | LINE_DETECT | IG=0, ACC=1, Brake=0, Back=0, LTurn=1, RTurn=0 | ✓ |
| 0x02 | MCU_VERSION | "PAJERO69XZA0120018" | ✓ |
| 0x03 | TIME_INFO | 2025-01-01 01:42:08（未设置） | ✓ |
| 0x05 | SYS_STATUS | firstPwrOn=0 | ✓ |
| 0x08 | TFT_DUTY | 0% | ✓ |
| 0x13 | VERSION_STR | sw="0302_20260527", boot="03" | ✓ |

### 3.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| cmd | 操作 | 返回值 | 状态 |
|-----|------|--------|------|
| 0x82 | Mute ON | rc=0 | ✓ |
| 0x82 | Mute OFF | rc=0 | ✓ |
| 0x84 | Backlight 50% | rc=0 | ✓ |
| 0x84 | Backlight 100% | rc=0 | ✓ |
| 0x81 | Refresh Init | rc=0 | ✓ |

### 3.3 结论

**Public 域 M2A/A2M 双向通信全部正常。MCU 固件缺陷仅影响 Radio 域。**

---

## 四、Key 域 — 已修复，SDK 切换至帕杰罗映射

### 4.1 M2A（MCU→ARM）测试结果

通过物理方控板 + minicom KeyTest 双路径触发：

**物理方控：**

| 按键值 | 帕杰罗功能 | 接收次数 | 状态 |
|--------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | 2 | ✓ |
| 0x04 | KEY_MUSIC 音乐 | 3 | ✓ |
| 0x08 | KEY_VOL_DEC 音量- | 2 | ✓ |
| 0x09 | KEY_VOL_INC 音量+ | 2 | ✓ |
| 0x0E | KEY_PREV 上一曲 | 3 | ✓ |
| 0x0F | KEY_NEXT 下一曲 | 2 | ✓ |
| 0x18 | KEY_ANSWER 接听 | 1 | ✓ |
| 0x19 | KEY_REJECT 挂断 | 1 | ✓ |
| 0x25 | KEY_CAMERA 摄像头 | 1 | ✓ |

含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），M2A 全链路无任何 keyValue 范围过滤，所有值正常接收。

**minicom 模拟：**

```bash
minicom -D /dev/ttyUSB0 -b 115200
xiexw:/$ KeyTest 1 0x19 0x01   # 按下挂断
xiexw:/$ KeyTest 1 0x19 0x00   # 弹起挂断
```

MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端 FrameRouter 同步打印 `KEY value=0x19 status=0x01`。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue (帕杰罗) | keyStatus | seq | 状态 |
|------|-------------------|-----------|-----|------|
| MODE | 0x0D | 0x01（短按） | - | 传输层 OK |
| MUTE | 0x0C | 0x01（短按） | - | 传输层 OK |
| 音量- | 0x08 | 0x01（短按） | 163 | 传输层 OK |
| 音量+ | 0x09 | 0x01（短按） | 162 | 传输层 OK |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK（传输层正常）。但 MCU 同时打印：

```
E: ARMCORE,mcucomm_notify_recv_data:msgType[2] not register proc fn
```

MCU 传输层正确处理了帧（返回 ACK），但应用层未注册 `MSG_TYPE_KEY` 的 A2M 接收处理函数，数据被丢弃。这与自测文档"KEY_A2M_KEY暂时不用实现"一致。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射修复

Key.xlsx 中帕杰罗使用"其它项目"映射表（行 44-73），原 SDK 使用 MC3 映射。已修复：

| 功能 | 修复前 (MC3) | 修复后 (帕杰罗) |
|------|-------------|---------------|
| 音量- | 0x0B | **0x08** |
| 音量+ | 0x0A | **0x09** |
| 上一曲 | 0x08 | **0x0E** |
| 下一曲 | 0x09 | **0x0F** |
| 接听 | 未定义 | **0x18** |
| 挂断 | 未定义 | **0x19** |
| 摄像头 | 未定义 | **0x25** |
| MODE | 0x01 | **0x0D** |
| MUTE | 0x02 | **0x0C** |

修复文件：

| 文件 | 改动 |
|------|------|
| `sdk/.../McuKeyClient.java` | MC3 常量 → 帕杰罗常量 |
| `contract/.../Commands.java` | 校验上限 0x0B → 0x25 |
| `demos/.../MainActivity.java` | 按钮值 + swcName 对齐帕杰罗 |

### 4.5 结论

**Key 域 M2A 方向：9 种按键全部正常接收，含 5 个扩展值。SDK 常量已从 MC3 切换至帕杰罗映射，Demo 按钮已对齐。A2M 方向：MCU 固件未实现，待 MCU 侧注册 `MSG_TYPE_KEY` 处理函数。**

---

## 五、软件层全局审计结论

对全部 7 层软件链路进行了逐模块审计：

| 层级 | 文件 | 检查结果 |
|------|------|---------|
| C 协议 | `mcu_protocol.c` | 帧编解码正确 |
| C 传输 | `mcu_transport.c` | 串口 I/O、回调链正确 |
| JNI | `jni_bridge.cpp` | body 字节传递正确 |
| Java 分发 | `FrameRouter.java` | msgType/cmd 路由正确 |
| Java 业务 | `VehicleFeature.java` | Public 26 个 M2A cmd 映射正确 |
| Java 业务 | `RadioFeature.java` | Radio 5 个 M2A cmd 映射正确 |
| Java 业务 | `KeyFeature.java` | Key 1 个 M2A cmd 映射正确 |
| Java 解析 | `Decoders.java` | 全部解析器与协议一致 |
| Java 编码 | `Commands.java` | 全部编码器与协议一致 |
| Java 发送 | `McuLink.java` | 帧组装正确 |
| SDK | `McuClient.java` 等 | 回调转发正确 |

**Android 中间件软件层的 MCU 通信代码没有 bug。**

---

## 六、问题汇总

| 编号 | 问题 | 严重程度 | 责任方 | 状态 |
|------|------|---------|--------|------|
| #1 | Radio FREQ 帧 P4-P6 全部为零 | 高 | MCU 固件 | 待修复 |
| #2 | Radio PS_PTY 帧 9 字节全部为零 | 高 | MCU 固件 | 待修复 |
| #3 | Radio RT 帧 64 字节全部为零 | 高 | MCU 固件 | 待修复 |
| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | 待修复 |

---

## 七、建议

1. **紧急**：将 #1-#3 的 MCU 固件缺陷报告发给 MCU 供应商，要求修复 Radio 域数据填充
2. **后续**：修复 #4 的 Key 映射问题，在 SDK 中增加帕杰罗车型的按键常量
3. **后续**：将 `sendKeyEvent` 的日志补全（当前 `McuBinder` 和 `McuKeyClient` 无日志）

-| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | 待修复 |

+| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | **已修复** |


Also update the "建议" section to remove the Key mapping fix from the pending items.


1. **紧急**：将 #1-#3 的 MCU 固件缺陷报告发给 MCU 供应商，要求修复 Radio 域数据填充
2. **后续**：修复 #4 的 Key 映射问题，在 SDK 中增加帕杰罗车型的按键常量
3. **后续**：将 `sendKeyEvent` 的日志补全（当前 `McuBinder` 和 `McuKeyClient` 无日志）

1. **紧急**：将 #1-#3 的 MCU 固件缺陷报告发给 MCU 供应商，要求修复 Radio 域数据填充
2. **已完成**：Key 映射已从 MC3 切换至帕杰罗（SDK + Demo）
3. **后续**：将 `sendKeyEvent` 的日志补全（当前 `McuBinder` 和 `McuKeyClient` 无日志）


1. **紧急**：将 #1-#3 的 MCU 固件缺陷报告发给 MCU 供应商，要求修复 Radio 域数据填充
2. **已完成**：Key 映射已从 MC3 切换至帕杰罗（SDK + Demo）
3. **后续**：将 `sendKeyEvent` 的日志补全（当前 `McuBinder` 和 `McuKeyClient` 无日志）

# QSJNIC MCU 通信全链路测试报告

## 基本信息

| 项目 | 内容 |
|------|------|
| 日期 | 2026-05-28 |
| 项目 | QSJNIC 车载 Android 中间件 |
| 版本 | v1.0.0-beta6 |
| MCU 固件 | `swVersion=0302_20260527` |
| MCU 硬件 | `hwVersion=PAJERO69XZA0120018` |
| 测试设备 | 车机 192.168.0.66 |
| 协议文档 | `docs/MCU_ARM_Reference/20260513/` |

---

## 一、测试范围

对 Android 中间件与 MCU 之间的全部三个业务域进行了端到端测试：

| 域 | MsgType | 测试项 | M2A | A2M |
|----|---------|--------|-----|-----|
| Public（车辆信号） | 0x01 | LINE_DETECT, MCU_VERSION, TIME_INFO, SYS_STATUS, TFT_DUTY, 等 | 6 项 | 5 项 |
| Radio（收音机） | 0x05 | FREQ, PS_PTY, RT, SEEK | 3 项 | 1 项 |
| Key（方控按键） | 0x02 | KEY_M2A_KEY, KEY_A2M_KEY | 0 项 | 3 项 |

---

## 二、Radio 域 — MCU 固件缺陷（已证实）

### 2.1 发现

搜台后 `valid`、`signal` 始终为 0，`onPsPty` 和 `onRadioText` 回调无数据。

### 2.2 排查方法

在 `FrameRouter.handleRadio()` 中增加原始 hex dump，直接打印 MCU 发来的 body 字节，绕过所有软件解析层。

### 2.3 实测数据

**FREQ 帧（cmd=0x01）— 搜台中：**
```
FREQ_BODY[7]=26 B0 00 42 00 00 00 | Byte12=0x00 (valid=0) Byte14(signal)=0x00
```
- 频率 P0-P1: `26 B0` → `26 C4`（99.04→99.24 MHz）✓
- 波段 P2: `00`=FM ✓
- 搜台模式 P3: `42`=SEEK_FF+STEREO ✓
- **valid P4 Byte12: `0x00`（bit7=0）** ✗
- **PTY P5 Byte13: `0x00`** ✗
- **signal P6 Byte14: `0x00`** ✗

**PS_PTY 帧（cmd=0x02）：**
```
PS_PTY[9]=00 00 00 00 00 00 00 00 00 | PTY=0x00 PS="(empty)"
```
- 9 字节全部为零

**RT 帧（cmd=0x03）：**
```
RT[64]=00 00 00 ... 00 00 | RT="(empty)"
```
- 64 字节全部为零

### 2.4 软件层排查

| 层 | 检查项 | 结果 |
|----|-------|------|
| C 协议层 `mcu_protocol.c` | payload 从 `raw+6` 开始 | ✓ |
| JNI `jni_bridge.cpp` | `body = payload+2`, `body_len = payload_len-2` | ✓ |
| Java FrameRouter | payload 直接传递 | ✓ |
| DomainBus → RadioFeature | body 原样转发 | ✓ |
| RadioFeature | `valid = (p[4]>>7)&1`, `signal = p[6]&0xFF` | ✓ |
| Decoders.parsePsPty | `pty = body[0]`, `ps = trimUtf8(body, 1, 8)` | ✓ |
| AIDL → SDK → App | 回调传递 | ✓ |

### 2.5 结论

**MCU 固件 `0302_20260527` 的 Radio 域 M2A 帧（FREQ/PS_PTY/RT）结构正确但数据载荷全为零。这是 MCU 固件缺陷，不是 Android 端软件问题。**

---

## 三、Public 域 — 全部正常 ✓

### 3.1 M2A（MCU→ARM）测试结果

| cmd | 接口 | 实测值 | 状态 |
|-----|------|--------|------|
| 0x01 | LINE_DETECT | IG=0, ACC=1, Brake=0, Back=0, LTurn=1, RTurn=0 | ✓ |
| 0x02 | MCU_VERSION | "PAJERO69XZA0120018" | ✓ |
| 0x03 | TIME_INFO | 2025-01-01 01:42:08（未设置） | ✓ |
| 0x05 | SYS_STATUS | firstPwrOn=0 | ✓ |
| 0x08 | TFT_DUTY | 0% | ✓ |
| 0x13 | VERSION_STR | sw="0302_20260527", boot="03" | ✓ |

### 3.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| cmd | 操作 | 返回值 | 状态 |
|-----|------|--------|------|
| 0x82 | Mute ON | rc=0 | ✓ |
| 0x82 | Mute OFF | rc=0 | ✓ |
| 0x84 | Backlight 50% | rc=0 | ✓ |
| 0x84 | Backlight 100% | rc=0 | ✓ |
| 0x81 | Refresh Init | rc=0 | ✓ |

### 3.3 结论

**Public 域 M2A/A2M 双向通信全部正常。MCU 固件缺陷仅影响 Radio 域。**

---

## 四、Key 域 — 已修复，SDK 切换至帕杰罗映射

### 4.1 M2A（MCU→ARM）测试结果

通过物理方控板 + minicom KeyTest 双路径触发：

**物理方控：**

| 按键值 | 帕杰罗功能 | 接收次数 | 状态 |
|--------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | 2 | ✓ |
| 0x04 | KEY_MUSIC 音乐 | 3 | ✓ |
| 0x08 | KEY_VOL_DEC 音量- | 2 | ✓ |
| 0x09 | KEY_VOL_INC 音量+ | 2 | ✓ |
| 0x0E | KEY_PREV 上一曲 | 3 | ✓ |
| 0x0F | KEY_NEXT 下一曲 | 2 | ✓ |
| 0x18 | KEY_ANSWER 接听 | 1 | ✓ |
| 0x19 | KEY_REJECT 挂断 | 1 | ✓ |
| 0x25 | KEY_CAMERA 摄像头 | 1 | ✓ |

含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），M2A 全链路无任何 keyValue 范围过滤，所有值正常接收。

**minicom 模拟：**

```bash
minicom -D /dev/ttyUSB0 -b 115200
xiexw:/$ KeyTest 1 0x19 0x01   # 按下挂断
xiexw:/$ KeyTest 1 0x19 0x00   # 弹起挂断
```

MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端 FrameRouter 同步打印 `KEY value=0x19 status=0x01`。

### 4.2 A2M（ARM→MCU）测试结果

通过 Vehicle Demo App 触发：

| 按键 | keyValue (帕杰罗) | keyStatus | seq | 状态 |
|------|-------------------|-----------|-----|------|
| MODE | 0x0D | 0x01（短按） | - | 传输层 OK |
| MUTE | 0x0C | 0x01（短按） | - | 传输层 OK |
| 音量- | 0x08 | 0x01（短按） | 163 | 传输层 OK |
| 音量+ | 0x09 | 0x01（短按） | 162 | 传输层 OK |

`seq` 为有效值证明帧已通过串口发送给 MCU 且收到了 ACK（传输层正常）。但 MCU 同时打印：

```
E: ARMCORE,mcucomm_notify_recv_data:msgType[2] not register proc fn
```

MCU 传输层正确处理了帧（返回 ACK），但应用层未注册 `MSG_TYPE_KEY` 的 A2M 接收处理函数，数据被丢弃。这与自测文档"KEY_A2M_KEY暂时不用实现"一致。

### 4.3 协议一致性

| 项目 | 协议 Key.xlsx | 代码 | 结果 |
|------|-------------|------|------|
| MsgType | 0x02 | `MsgType.KEY = 0x02` | ✓ |
| M2A cmd | 0x01 | `Cmds.Key.M2A_KEY = 0x01` | ✓ |
| A2M cmd | 0x81 | `Cmds.Key.A2M_KEY = 0x81` | ✓ |
| P0 KeyValue | Byte8 | `body[0] & 0xFF` | ✓ |
| P1 KeyStatus | Byte9 | `body[1] & 0xFF` | ✓ |

### 4.4 按键值映射修复

Key.xlsx 中帕杰罗使用"其它项目"映射表（行 44-73），原 SDK 使用 MC3 映射。已修复：

| 功能 | 修复前 (MC3) | 修复后 (帕杰罗) |
|------|-------------|---------------|
| 音量- | 0x0B | **0x08** |
| 音量+ | 0x0A | **0x09** |
| 上一曲 | 0x08 | **0x0E** |
| 下一曲 | 0x09 | **0x0F** |
| 接听 | 未定义 | **0x18** |
| 挂断 | 未定义 | **0x19** |
| 摄像头 | 未定义 | **0x25** |
| MODE | 0x01 | **0x0D** |
| MUTE | 0x02 | **0x0C** |

修复文件：

| 文件 | 改动 |
|------|------|
| `sdk/.../McuKeyClient.java` | MC3 常量 → 帕杰罗常量 |
| `contract/.../Commands.java` | 校验上限 0x0B → 0x25 |
| `demos/.../MainActivity.java` | 按钮值 + swcName 对齐帕杰罗 |

### 4.5 结论

**Key 域 M2A 方向：9 种按键全部正常接收，含 5 个扩展值。SDK 常量已从 MC3 切换至帕杰罗映射，Demo 按钮已对齐。A2M 方向：MCU 固件未实现，待 MCU 侧注册 `MSG_TYPE_KEY` 处理函数。**

---

## 五、软件层全局审计结论

对全部 7 层软件链路进行了逐模块审计：

| 层级 | 文件 | 检查结果 |
|------|------|---------|
| C 协议 | `mcu_protocol.c` | 帧编解码正确 |
| C 传输 | `mcu_transport.c` | 串口 I/O、回调链正确 |
| JNI | `jni_bridge.cpp` | body 字节传递正确 |
| Java 分发 | `FrameRouter.java` | msgType/cmd 路由正确 |
| Java 业务 | `VehicleFeature.java` | Public 26 个 M2A cmd 映射正确 |
| Java 业务 | `RadioFeature.java` | Radio 5 个 M2A cmd 映射正确 |
| Java 业务 | `KeyFeature.java` | Key 1 个 M2A cmd 映射正确 |
| Java 解析 | `Decoders.java` | 全部解析器与协议一致 |
| Java 编码 | `Commands.java` | 全部编码器与协议一致 |
| Java 发送 | `McuLink.java` | 帧组装正确 |
| SDK | `McuClient.java` 等 | 回调转发正确 |

**Android 中间件软件层的 MCU 通信代码没有 bug。**

---

## 六、问题汇总

| 编号 | 问题 | 严重程度 | 责任方 | 状态 |
|------|------|---------|--------|------|
| #1 | Radio FREQ 帧 P4-P6 全部为零 | 高 | MCU 固件 | 待修复 |
| #2 | Radio PS_PTY 帧 9 字节全部为零 | 高 | MCU 固件 | 待修复 |
| #3 | Radio RT 帧 64 字节全部为零 | 高 | MCU 固件 | 待修复 |
| #4 | Key 按键映射不匹配（MC3 vs 帕杰罗） | 低 | SDK | **已修复** |

---

## 七、建议

1. **紧急**：将 #1-#3 的 MCU 固件缺陷报告发给 MCU 供应商，要求修复 Radio 域数据填充
2. **后续**：修复 #4 的 Key 映射问题，在 SDK 中增加帕杰罗车型的按键常量
3. **后续**：将 `sendKeyEvent` 的日志补全（当前 `McuBinder` 和 `McuKeyClient` 无日志）

-2. **后续**：修复 #4 的 Key 映射问题，在 SDK 中增加帕杰罗车型的按键常量

+2. **已完成**：Key 映射已从 MC3 切换至帕杰罗（SDK + Demo）


Switch SDK key constants from MC3 to Pajero mapping

1. McuKeyClient.java: replace MC3 constants with Pajero values
2. Commands.java: expand key validation range 0x0B → 0x25
3. MainActivity.java: update demo A2M buttons to Pajero values


Updated task #1 status


两份文档都已更新：

- **`imgs/full_test_report.md`** — 第四节 Key 域全面重写，包含 M2A 实测数据、minicom 命令、A2M `not register proc fn` 发现、已修复确认
- **`docs/MCU_ARM_Reference/20260513/方控按键测试报告_20260529.md`** — 独立方控测试文档，minicom 命令行完整可复制


minicom -b 921600 -o -D /dev/cu.usbmodem21302，这个命令有没有更新到文档中，我没看到啊'/Users/admin/workspace/jyq/qsjnic/docs/MCU_ARM_Reference/20260513/方控按键测试报告_20260529.md'


The user wants me to update the minicom command in the document with the actual parameters they use: baud rate 921600 and device /dev/cu.usbmodem21302.

Let me update the document with this specific command.


```bash
# 安装 minicom (macOS)
brew install minicom

# 安装 minicom (Linux)
sudo apt install minicom

# 连接 MCU 串口（根据实际设备名调整 /dev/ttyUSB0）
minicom -D /dev/ttyUSB0 -b 115200
```

波特率及其他串口参数以 MCU 固件实际配置为准。连接成功后出现 MCU Shell 提示符 `xiexw:/$`。

```bash
# 安装 minicom (macOS)
brew install minicom

# 安装 minicom (Linux)
sudo apt install minicom

# 连接 MCU 串口（本次测试实际参数）
minicom -b 921600 -o -D /dev/cu.usbmodem21302
```

| 参数 | 说明 |
|------|------|
| `-b 921600` | 波特率 921600 |
| `-o` | 不初始化调制解调器 |
| `-D /dev/cu.usbmodem21302` | MCU 串口设备路径（macOS），Linux 通常为 `/dev/ttyUSB0` |

连接成功后出现 MCU Shell 提示符 `xiexw:/$`。


```bash
# 安装 minicom (macOS)
brew install minicom

# 安装 minicom (Linux)
sudo apt install minicom

# 连接 MCU 串口（本次测试实际参数）
minicom -b 921600 -o -D /dev/cu.usbmodem21302
```

| 参数 | 说明 |
|------|------|
| `-b 921600` | 波特率 921600 |
| `-o` | 不初始化调制解调器 |
| `-D /dev/cu.usbmodem21302` | MCU 串口设备路径（macOS），Linux 通常为 `/dev/ttyUSB0` |

连接成功后出现 MCU Shell 提示符 `xiexw:/$`。

# 方控按键 M2A 通信测试报告

## 基本信息

| 项目 | 内容 |
|------|------|
| 日期 | 2026-05-29 |
| 项目 | QSJNIC 车载 Android 中间件 |
| 版本 | v1.0.0-beta6 |
| MCU 固件 | swVersion=0302_20260527 |
| MCU 硬件 | hwVersion=PAJERO69XZA0120018 |
| 测试设备 | 车机 192.168.0.66 |
| 协议文档 | `docs/MCU_ARM_Reference/Key.xlsx` → "其它项目" 映射表 |
| MCU 方控自测文档 | `docs/MCU_ARM_Reference/1.方控和车速自测.txt` |
| 串口工具 | minicom (Linux/macOS), Xshell (Windows) |

---

## 一、测试前提

Android 中间件服务 (`com.qsjnic.mcu.service`) 必须与 MCU 建链成功。

---

## 二、实物测试（方控板接线）

### 2.1 接线方式

- 方控板 KEY 线 → 车机尾线 SWC_L
- 方控板 GND 线  → 车机尾线 GND

### 2.2 MCU 端日志

每次按下方控按键，MCU 串口打印如下格式日志：

```
I(0000025683) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[TRIGGER]
[ARM_CORE,write data:] ff,aa,00,0b,08,06,02,01,04,01,de
I(0000026043) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[IDLE]
[ARM_CORE,write data:] ff,aa,00,0b,09,06,02,01,04,00,de
```

### 2.3 串口帧结构解析

以 `ff,aa,00,0b,08,06,02,01,04,01,de` 为例：

| 字节 | 值 | 含义 |
|------|-----|------|
| H0-H1 | ff aa | 帧头 |
| L0-L1 | 00 0b | 帧长度 = 11 字节 |
| Seq | 08 | 序列号 |
| Type | 06 | 帧类型 |
| MsgType | **02** | KEY 域 |
| Cmd | **01** | M2A_KEY (MCU→ARM) |
| P0 | **04** | KeyValue (body[0]) |
| P1 | **01** | KeyStatus (body[1]) |
| CS | de | 校验和 |

### 2.4 Android 端日志

MCU 帧到达 ARM 后，FrameRouter 打印：

```
I/FrameRouter: KEY value=0x04 status=0x01
```

---

## 三、模拟测试（minicom 串口命令）

在不接实物方控板时，通过 USB 转串口模块连接 MCU 调试串口，使用 minicom 直接注入按键帧。

### 3.1 minicom 连接 MCU

```bash
# 安装 minicom (macOS)
brew install minicom

# 安装 minicom (Linux)
sudo apt install minicom

# 连接 MCU 串口（根据实际设备名调整 /dev/ttyUSB0）
minicom -D /dev/ttyUSB0 -b 115200
```

波特率及其他串口参数以 MCU 固件实际配置为准。连接成功后出现 MCU Shell 提示符 `xiexw:/$`。

### 3.2 KeyTest 命令格式

在 minicom 终端中直接输入：

```
KeyTest <测试项> <按键值> <按键状态>
```

| 参数 | 说明 | 示例 |
|------|------|------|
| 测试项 | 固定为 `1`（M2A 按键测试） | 1 |
| 按键值 | 帕杰罗 KeyValue（0x00-0x25） | 0x19 |
| 按键状态 | 0x01=按下(TRIGGER), 0x00=弹起(IDLE) | 0x01 |

### 3.3 单键示例（挂断键）

在 minicom 中依次输入按下和弹起：

```
xiexw:/$ KeyTest 1 0x19 0x01
I(0000490647) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x01
[ARM_CORE,write data:] ff,aa,00,0b,1c,06,02,01,19,01,b5

xiexw:/$ KeyTest 1 0x19 0x00
I(0000535107) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x00
[ARM_CORE,write data:] ff,aa,00,0b,1d,06,02,01,19,00,b5
```

MCU 打印 `[ARM_CORE,write data:]` 表示帧已从串口 TX 发出，Android 端可从 FrameRouter 日志确认接收。

### 3.4 全部 9 个帕杰罗按键 minicom 命令

以下命令直接复制到 minicom 终端逐行执行：

```
# 语音 (0x03)
KeyTest 1 0x03 0x01
KeyTest 1 0x03 0x00

# 音乐 (0x04)
KeyTest 1 0x04 0x01
KeyTest 1 0x04 0x00

# 音量- (0x08)
KeyTest 1 0x08 0x01
KeyTest 1 0x08 0x00

# 音量+ (0x09)
KeyTest 1 0x09 0x01
KeyTest 1 0x09 0x00

# 上一曲 (0x0E)
KeyTest 1 0x0E 0x01
KeyTest 1 0x0E 0x00

# 下一曲 (0x0F)
KeyTest 1 0x0F 0x01
KeyTest 1 0x0F 0x00

# 接听 (0x18)
KeyTest 1 0x18 0x01
KeyTest 1 0x18 0x00

# 挂断 (0x19)
KeyTest 1 0x19 0x01
KeyTest 1 0x19 0x00

# 摄像头 (0x25)
KeyTest 1 0x25 0x01
KeyTest 1 0x25 0x00
```

### 3.5 同时监控 Android 端日志

另开一个终端，通过 ADB 实时查看 Android 端接收情况：

```bash
adb -s 192.168.0.66:5555 logcat -v time | grep --line-buffered "KEY value="
```

每执行一条 KeyTest 命令，Android 端应打印对应的 KEY value 日志。

---

## 四、帕杰罗方控按键值定义

MCU 固件侧枚举（`docs/MCU_ARM_Reference/1.方控和车速自测.txt`）：

```c
typedef enum
{
    EN_KEYMGR_SWC_TYPE_IDLE             = 0x00,//空闲
    EN_KEYMGR_SWC_TYPE_VOLUME_DOWN      = 0x08,//音量减
    EN_KEYMGR_SWC_TYPE_VOLUME_UP        = 0x09,//音量加
    EN_KEYMGR_SWC_TYPE_NEXT             = 0x0F,//下一曲
    EN_KEYMGR_SWC_TYPE_PREV             = 0x0E,//上一曲
    EN_KEYMGR_SWC_TYPE_MUSIC            = 0x04,//音乐
    EN_KEYMGR_SWC_TYPE_SPEECH           = 0x03,//语音
    EN_KEYMGR_SWC_TYPE_ANSWER           = 0x18,//接听
    EN_KEYMGR_SWC_TYPE_REJECT           = 0x19,//挂断
    EN_KEYMGR_SWC_TYPE_CAMERA           = 0x25,//摄像头
} EN_KEYMGR_SWC_TYPE;
```

对应 Key.xlsx "其它项目" 映射表（行 44-73）。

---

## 五、Android 端 M2A 实测结果

所有 9 种按键均通过物理方控板 + minicom KeyTest 双路径触发，Android 端 FrameRouter 完整捕获。

| 按键值 | 帕杰罗功能 | MC3范围内? | 接收次数 | 状态 |
|--------|-----------|-----------|---------|------|
| 0x03 | KEY_VOICE 语音 | ✓ | 2 | 正常 |
| 0x04 | KEY_MUSIC 音乐 | ✓ | 3 | 正常 |
| 0x08 | KEY_VOL_DEC 音量- | ✓ | 2 | 正常 |
| 0x09 | KEY_VOL_INC 音量+ | ✓ | 2 | 正常 |
| 0x0E | KEY_PREV 上一曲 | ✗ 扩展值 | 3 | 正常 |
| 0x0F | KEY_NEXT 下一曲 | ✗ 扩展值 | 2 | 正常 |
| 0x18 | KEY_ANSWER 接听 | ✗ 扩展值 | 1 | 正常 |
| 0x19 | KEY_REJECT 挂断 | ✗ 扩展值 | 1 | 正常 |
| 0x25 | KEY_CAMERA 摄像头 | ✗ 扩展值 | 1 | 正常 |

### Android 端日志示例

```
I/FrameRouter: KEY value=0x04 status=0x01    ← 音乐键按下
I/FrameRouter: KEY value=0x04 status=0x00    ← 音乐键弹起
I/FrameRouter: KEY value=0x0E status=0x01    ← 上一曲按下
I/FrameRouter: KEY value=0x0E status=0x00    ← 上一曲弹起
I/FrameRouter: KEY value=0x0F status=0x01    ← 下一曲按下
I/FrameRouter: KEY value=0x0F status=0x00    ← 下一曲弹起
I/FrameRouter: KEY value=0x09 status=0x01    ← 音量+按下
I/FrameRouter: KEY value=0x08 status=0x01    ← 音量-按下
I/FrameRouter: KEY value=0x03 status=0x01    ← 语音键按下
I/FrameRouter: KEY value=0x18 status=0x01    ← 接听键按下
I/FrameRouter: KEY value=0x19 status=0x01    ← 挂断键按下
I/FrameRouter: KEY value=0x25 status=0x01    ← 摄像头键按下
```

---

## 六、Android 端 M2A 接收链路确认

```
MCU 串口 TX
    ↓
C 协议层 (mcu_protocol.c) — 帧解码
    ↓
JNI (jni_bridge.cpp) — body 字节提取
    ↓
FrameRouter.dispatch() — msgType=0x02 路由
    ↓
FrameRouter.handleKey() — cmd=0x01, 无 keyValue 范围校验
    ↓
KeyFeature.onFrame() — 透传至 Decoders
    ↓
Decoders.parseKeyControl() — 仅校验 body.length >= 2
    ↓
broadcastKeyEvent(keyValue, keyStatus) — 广播至所有监听者
    ↓
Vehicle Demo App (IMcuKeyListener.onKeyEvent)
```

**全链路无任何 keyValue 范围过滤。MCU 上报的任何值（0x00-0x25）均可完整到达应用层。**

---

## 七、结论

1. **M2A 方向**：9 种帕杰罗方控按键全部正常接收，含 5 个 MC3 范围外扩展值（0x0E/0x0F/0x18/0x19/0x25），按下和弹起事件完整
2. **串口协议**：帧结构（ff aa + len + seq + type + msgType=02 + cmd=01 + keyValue + keyStatus + cs）一致
3. **SDK 已修复**：McuKeyClient 常量已从 MC3 切换为帕杰罗映射，Commands.Key.key() 校验范围已放宽至 0x25，Vehicle Demo 按钮已对齐帕杰罗值
4. **A2M 方向**：MCU 固件 `0302_20260527` 未注册 `MSG_TYPE_KEY` 的 A2M 处理函数（`msgType[2] not register proc fn`），A2M KEY 暂时不可用，待 MCU 固件更新

---

## 八、A2M 按键发送现状

Android 端通过 Vehicle Demo 发送 A2M 按键时：

- 传输层正常：MCU 收到帧并回 ACK（Android 拿到有效 seq）
- 应用层未实现：MCU 打印 `E: msgType[2] not register proc fn`
- 自测文档写明：`KEY_A2M_KEY暂时不用实现`

A2M 方向需等待 MCU 固件注册 `MSG_TYPE_KEY` 的接收处理函数后可用。

---

## 九、参考文档

| 文档 | 路径 |
|------|------|
| Key 协议 (MC3 + 其它项目映射) | `docs/MCU_ARM_Reference/Key.xlsx` |
| 方控和车速自测 (MCU 侧) | `docs/MCU_ARM_Reference/1.方控和车速自测.txt` |
| MCU-ARM 接口清单 | `docs/MCU_ARM_Reference/20260513/MCU_ARM_接口文档清单与明细_20260513.md` |
| 全链路测试报告 | `imgs/full_test_report.md` |
| SDK Key 常量 (已更新为帕杰罗) | `sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java` |
| Key 编码校验 (已放宽至 0x25) | `contract/src/main/java/com/qsjnic/mcu/domain/Commands.java` |
| Vehicle Demo (帕杰罗映射) | `demos/vehicle-demo/app/src/main/java/com/qsjnic/demo/vehicle/MainActivity.java` |

---

Android 中间件测试组
2026-05-29

+# 连接 MCU 串口（本次测试实际参数）

+minicom -b 921600 -o -D /dev/cu.usbmodem21302

-波特率及其他串口参数以 MCU 固件实际配置为准。连接成功后出现 MCU Shell 提示符 `xiexw:/$`。

+| 参数 | 说明 |

+| `-o` | 不初始化调制解调器 |

+| `-D /dev/cu.usbmodem21302` | MCU 串口设备路径（macOS），Linux 通常为 `/dev/ttyUSB0` |

在 minicom 终端中直接输入：


Done. Let me also update the full_test_report.md to keep it consistent.


已更新，写入了你的实际参数 `minicom -b 921600 -o -D /dev/cu.usbmodem21302`，附带参数说明。


Key mapping MC3→Pajero fix complete, code + docs both updated. Radio signal/valid=0 confirmed as MCU firmware issue. Next: wait for MCU vendor fix.