jjsch-dev/r5xx-fingerprint-testbench
GitHub: jjsch-dev/r5xx-fingerprint-testbench
基于 ESP32-S3 的 JSON 驱动测试台,用于通过 UART 探索和逆向 Synochip R5xx 指纹传感器协议。
Stars: 0 | Forks: 0
# ESP32-S3 R5xx Synochip 协议测试台
这是一个交互式、基于 JSON 驱动的硬件测试台,用于使用 ESP32-S3 通过 UART 对基于 Synochip 的生物识别传感器(R5xx、R502、R503、R558 系列)进行逆向工程和探索。
## 功能
- **无状态桥接:** 通过 USB 串口(115200 波特率)的串口转 UART 命令调度器。
- **顺序 JSON 数组:** 发送一批低级命令,这些命令将按顺序执行,前提是上一步返回 `0x00` (OK)。
- **自动硬件重试:** 内置轮询参数(`retries` 和 `retryDelay`),用于等待用户操作的命令(例如,等待手指放置)。
- **动态 ACK 解析:** 验证 Synochip 帧校验和并解码扩展的 payload ACK 响应(例如,在 1:N 搜索中提取 `Matched ID` 和 `Score`)。
- **错误传播:** 协议失败时立即中止序列执行,以防止无效操作。
## 硬件设置
| ESP32-S3 引脚 | 传感器引脚 | 描述 |
| :--- | :--- | :--- |
| **GPIO 18** | 传感器 RX | ESP32 TX -> 传感器 RX |
| **GPIO 17** | 传感器 TX | ESP32 RX <- 传感器 TX |
| **GND** | GND | 共地 |
| **3.3V / 5V** | VCC | 电源(请查阅传感器规格) |
*默认波特率:* `57600 baud`(Synochip 出厂默认标准)。
## JSON 命令 Schema
命令通过 Serial Monitor(以 `\n` 结尾)作为单个 JSON 对象或 JSON 对象数组发送。
### 单命令对象
```
{
"pid": "01",
"data": "4060040400",
"retries": 0,
"retryDelay": 200
}
```
* `pid` (*string, 可选*):十六进制格式的数据包标识符(默认:`"01"` 表示命令包)。
* `data` (*string*):十六进制字符串格式的原始指令 payload。
* `retries` (*int, 可选*):如果响应状态不为 `0x00` 时的重试次数(默认:`0`)。
* `retryDelay` (*int, 可选*):重试之间的延迟(毫秒)(默认:`200`)。
## 协议命令目录
### 1. 验证(1:N 搜索与反馈)
捕获图像,转换为 Buffer 1,搜索内存,并在成功时亮起绿色 LED。
```
[
{"data": "01", "retries": 15, "retryDelay": 300},
{"data": "0201"},
{"data": "040100000063"},
{"data": "4060040400"}
]
```
### 2. 录入(双步模板创建与 Flash 存储)
捕获手指两次,创建合并模板 (RegModel),将其存储在 Slot ID #1 (0x0001) 中,并提供绿色 LED 反馈。
```
[
{"data": "01", "retries": 15, "retryDelay": 300},
{"data": "0201"},
{"data": "01", "retries": 15, "retryDelay": 300},
{"data": "0202"},
{"data": "05"},
{"data": "06010001"},
{"data": "4060040400"}
]
```
### 3. 全局中止 / 软复位
强制传感器 MCU 中止挂起的采样操作,清空内部缓冲区,关闭 LED 指示灯,并返回 IDLE 状态。
```
{"data": "33"}
```
## 示例执行输出
```
=== Starting JSON Sequence (4 Steps) ===
--- Step 1 of 4 ---
[TX -> Sensor] PID: 0x01 | Data Length: 1 bytes
[RX Parsed]: ACK | Status: No finger on sensor | Checksum: VALID
[Retry Attempt 1/15 after 300 ms...]
[RX Parsed]: ACK | Status: OK (Success) | Checksum: VALID
--- Step 2 of 4 ---
[RX Parsed]: ACK | Status: OK (Success) | Checksum: VALID
--- Step 3 of 4 ---
[RX Parsed]: ACK | Status: OK (Success) | Matched ID: 1 | Score: 100 | Checksum: VALID
--- Step 4 of 4 ---
[RX Parsed]: ACK | Status: OK (Success) | Checksum: VALID
=== Sequence Completed Successfully ===
```
### Aura LED 控制 (`0x40`)
控制传感器玻璃周围的环形/光晕 LED 指示灯。
#### Payload 结构分解
以 `4060040400` 为例:
* `40` — **操作码**:Aura LED 控制命令。
* `60` — **控制码**:模式(例如,`0x60` 表示静态/常亮照明)。
* `04` — **速度/周期**:闪烁或脉冲速度参数。
* `04` — **颜色索引**:硬件颜色位掩码字节(参见下方参考)。
* `00` — **循环计数**:重复次数(`0x00` = 连续/静态)。
#### 颜色位掩码参考
| 字节值 | 颜色 / 状态 | 硬件通道 |
| :---: | :--- | :--- |
| `0x00` | **关闭** | 无 |
| `0x01` | **红色** | 通道 1 |
| `0x02` | **蓝色** | 通道 2 |
| `0x04` | **绿色** | 通道 3 |
*注意:可以对位进行组合以生成次要颜色(例如,`0x03` 表示紫色,`0x05` 表示黄色,`0x06` 表示青色,`0x07` 表示白色)。*
#### JSON 命令示例
* **绿色(成功 / 就绪):**
[{"data": "4060040400"}]
* **红色(错误 / 拒绝):**
[{"data": "4060040100"}]
* **蓝色(忙碌 / 处理中):**
[{"data": "4060040200"}]
* **LED 关闭:**
[{"data": "4060040000"}]
## 读取系统参数 (`0x0F`)
查询系统配置参数,包括总库容量、安全级别和设备地址。
### 硬件注意事项:
* 确认容量:在此特定型号上,报告的总存储容量为 `100` 个模板 (`0x0064`)。
* 静态 Payload:请求包中不需要参数字节。
### Payload 结构分解
以 `0F` 为例:
* 0F — 操作码:读取系统参数命令。
### JSON 命令示例
* 读取系统配置:
```
{"data": "0F"}
```
### 响应数据分解(16 字节 Payload)
当传感器响应 ACK 状态:0x00 时,16 字节的 payload 映射如下:
* 字节 0–1 (000C):状态寄存器 — 内部硬件状态标志。
* 字节 2 (06):波特率倍数 ($N$) — 计算公式为 N * 9600 bps (0x06 = 57,600 bps)。
* 字节 3–5 (000000):保留 — 填充 / 未使用的字节。
* 字节 6–7 (0064):容量 — 最大模板容量 (0x0064 = 100 个模板)。
* 字节 8–9 (0004):安全级别 — 误识率阈值(级别 1 到 5)。
* 字节 10–15 (46504D0054585246):供应商 ID — ASCII 字符串 (FPM\0TXRF)。
## 读取系统参数 (`0x0F`)
查询系统配置参数,包括总库容量、安全级别和设备地址。
### 硬件注意事项:
* 确认容量:在此特定型号上,报告的总存储容量为 `100` 个模板 (`0x0064`)。
* 静态 Payload:请求包中不需要参数字节。
### Payload 结构分解
以 `0F` 为例:
* 0F — 操作码:读取系统参数命令。
### JSON 命令示例
* 读取系统配置:
```
{"data": "0F"}
```
### 响应数据分解(16 字节 Payload)
当传感器响应 `ACK Status: 0x00` 时,16 字节的 payload 映射如下:
* 字节 0–1 (`000C`):状态寄存器 — 内部硬件状态标志。
* 字节 2 (`06`):波特率倍数 ($N$) — 计算公式为 `N * 9600 bps` (`0x06` = 57,600 bps)。
* 字节 3–5 (`000000`):保留 — 填充 / 未使用的字节。
* 字节 6–7 (`0064`):容量 — 最大模板容量 (`0x0064` = 100 个模板)。
* 字节 8–9 (`0004`):安全级别 — 误识率阈值(级别 1 到 5)。
* 字节 10–15 (`46504D0054585246`):供应商 ID — ASCII 字符串 (`FPM\0TXRF`)。
## 设置系统参数 (`0x0E`)
修改可配置的运行时系统参数,如波特率倍数、安全级别或数据包大小。
### 硬件注意事项:
* **波特率更改**:更改参数 `0x06` 会立即改变传感器的 UART 速度。必须相应地重新配置主机 UART。
* **数据包大小范围**:参数 `0x05` 定义了批量传输 (`PID 0x02 / PID 0x08`) 的块大小,如模板上传/下载 (`0x08/0x09`) 和原始图像传输 (`0x0A`)。
### 可配置参数参考
| 参数字节 | 名称| 有效值 | 描述 |
| :---: | :--- | :--- | :--- |
`0x04` | **安全级别**| `0x01` 到 `0x05` | 调整识别阈值的严格程度。默认:4。 |
`0x05` | **数据包大小** | `0x00` 到 `0x03` | `0` = 32B, `1` = 64B, `2` = 128B, `3` = 256B payload 块。 |
`0x06` | **波特率倍数** | `0x01` 到 `0x0C` | N * 9600 bps 的倍数 `N` (`0x06` = `57600` bps, `0x0C` = `115200` bps)。 |
### JSON 命令示例
将安全级别设置为 3(平衡 FAR/FRR):
```
{"data": "0E0403"}
```
* 将数据包大小设置为 128 字节(默认):
```
{"data": "0E0502"}
```
* 将数据包大小设置为 256 字节(快速传输):
```
{"data": "0E0503"}
```
## 读取有效模板数 (`0x1D`)
返回库中当前存储的有效指纹模板总数。
### 硬件注意事项:
* RAM 缓存依赖:报告存储在活动 RAM 索引表中的值;在硬件上电循环之前的 0x0D 命令之后,可能会产生过时的计数。
### Payload 结构分解
以 `1D` 为例:
* 1D — 操作码:读取有效模板数命令。
### JSON 命令示例
获取模板计数:
```
{"data": "1D"}
```
## 读取索引表 (`0x1F`)
检索一个 32 字节(256 位)的内存映射,指示已占用和空闲的模板存储槽。
### 硬件注意事项:
* 位排序(低位优先):在每个字节内,位从 LSB 映射到 MSB(位 0 对应该字节中最低的 Slot ID)。
* 页面参数:需要一个页面索引字节(`0x00` 涵盖槽 0 到 255)。
### Payload 结构分解
以 1F00 为例:
* `1F` — 操作码:读取索引表命令。
* `00` — 页面索引:内存页表(`0x00` 表示模板 ID 0 到 255)。
### 位掩码解释参考
位状态 | 存储 Slot 状态 |
| :---: | :--- |
0 | **空槽**(可用于录入)
1 | **已占用槽**(存在有效模板)
示例:第一个字节 `0x0D` `(00001101₂)` 表示 Slot ID 0、ID 2 和 ID 3 已被占用,而 ID 1 为空。
### JSON 命令示例
* 读取页面 0 索引映射:
```
{"data": "1F00"}
```
## 删除模板范围 (`0x0C`)
通过指定起始 ID 和数量,删除连续范围内的指纹模板。
### 硬件注意事项:
* 立即更新 RAM:立即修改 Flash 和 RAM 索引表,无需上电循环。
### Payload 结构分解
以 `0C00010001` 为例:
* `0C` — 操作码:删除模板命令。
* `0001` — 起始 ID:起始模板槽的高/低字节(`0x0001` = ID 1)。
* `0001` — 数量:要清除的槽数的高/低字节(`0x0001` = 1 个模板)。
### JSON 命令示例
* 删除单个模板(ID 1):
```
{"data": "0C00010001"}
```
* 删除块范围(ID 0 到 3 — 4 个模板):
```
{"data": "0C00000004"}
```
## 清空 Flash 数据库 (`0x0D`)
从物理 Flash 存储数据库中清除所有存储的指纹模板。
### 硬件注意事项:
* 无自动 RAM 刷新:在 SPI Flash 上执行物理扇区擦除,但在该固件版本中未能自动清除活动 RAM 索引缓存。
* 需要上电循环:在执行 0x0D 后,需要硬件上电循环 (POR) 或复位序列,以将 RAM 索引表同步回零。
### Payload 结构分解
以 `0D` 为例:
* `0D` — 操作码:清空数据库命令。
### JSON 命令示例
* 格式化 / 擦除所有模板:
```
{"data": "0D"}
```
标签:ESP32, Homebrew安装, UML, 串口通信, 云资产清单, 指纹传感器, 物联网, 硬件测试工具, 逆向工程