Files
MAG160C/csdk/README.md
T
ZXCLI 0bfb926892 完成官方管线全量逆向与 demo3 v5 复刻,清理仓库
- 逆向:Ghidra/IDA 全量反编译 CoreSDKLib.dll/ThermalSDK.dll/libthermalSDK.so/
  libcoresdk.so(ARM64)/libmagcore.so,导出 analysis/ida/export/
- 解码官方渲染管线:DDT 校准表加载->快门端点选择->Q12 插值->ref(4x type1 帧
  均值)->NUC 查表->盲元补偿->窗口->LUT1024 重建->2x 升采样->调色板
- 逐像素验证:NUC+盲元 0/19200、插值 0 误差、2x 0/76800、窗口一致
- demo3 v5:完整复刻官方管线(含 DDT 解析、FFC 状态机、快门温度驱动),
  修复 load_ddt 表错位导致的零像素问题
- 鬼影根因分析写入 analysis/reverse_20260813_full.md
- 心跳/恢复机制:analysis/session_state.md + tools/resume_rev.ps1
- 新增 tsdk_pair3 增强采集工具;历史工具归档 csdk/tools/legacy/;
  根目录抓帧残留删除,历史文档归档 analysis/history/
- csdk/README.md 完整使用文档;.gitignore/.gitattributes 补 LFS 规则
2026-08-13 23:16:12 +08:00

226 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MAG160C C SDK (csdk/)
MAG160C 热像仪(160×120USB VID 0x833C)的纯 C 重新实现,基于对原厂
Windows/Linux/Android SDK 的完整逆向(见 `../analysis/reverse_20260813_full.md`)。
包含:USB 会话层、帧解析/流组装、温度换算、TCM 板通信、以及**官方渲染管线的
逐像素复刻**demo3 v5)。
## 目录结构
```
csdk/
include/mag160c/
mag160c.h 公共 C ABI(错误域、协议常量、帧格式、温度、TCM)
mag160c_display.h FFC 调度器 + 显示辅助(ref rebase 等)
src/
mag160c_internal.h 内部共享(last-error
mag160c_error.c TLS last-error + 错误名
mag160c_frame.c 0x1bb1b11b 帧解析 + 流组装器
mag160c_temp.c Calibration / ConvertResponse2Temperature / T2E
mag160c_tcm.c FTDICommand 0x7e 组帧 + 旋转/指示灯构建
mag160c_ir.c libusb 会话(link/start/stop/ffc/info/回调/FFC调度)
mag160c_display.c 显示辅助(FFC 调度器、ref rebase、坏点)
mag160c_tables.h T2E/E2TAccQ10 温度表(从二进制提取)
mag160c_official_*.h 官方调色板 / LUT1024 / T2E(从官方活体抓取导出)
tools/
mag160c_demo3.c 主程序:官方管线复刻(DDT+NUC+盲元+窗口+LUT+2x
tsdk_pair2.c 官方 ThermalSDK 同帧抓帧工具(含表/盲元/快门)
tsdk_pair3.c 增强采集(DDT 复制、完整端点表、盲元、h1024/cdf)
mag160c_cli.c CLIir-info/ffc/start/stop/tcm-rotate/tcm-light 等
mag160c_csdk_stream_test.c csdk 流测试
legacy/ 历史探索工具(归档,勿用)
tests/ test_frame / test_temp / test_tcm / test_api / test_display
CMakeLists.txt CMake 构建(可选;当前环境直接用 gcc)
WINDOWS_TESTING.md Windows 硬件测试指南(USBPcap/Wireshark/MinGW
```
## 构建
### 方式 A:直接 GCC(当前 Windows 环境)
```powershell
# CLI 工具
gcc -O2 -w -DMAG160C_STATIC -I"csdk\third_party\libusb\win64" -I"csdk\include" -I"csdk\src" `
-o build-artifacts\mag160c_cli.exe csdk\tools\mag160c_cli.c `
csdk\src\mag160c_ir.c csdk\src\mag160c_frame.c csdk\src\mag160c_temp.c `
csdk\src\mag160c_tcm.c csdk\src\mag160c_error.c csdk\src\mag160c_display.c `
csdk\third_party\libusb\win64\libusb-1.0.x64.a
# 主程序 demo3(官方管线复刻)
gcc -O2 -w -DMAG160C_STATIC -I"csdk\third_party\libusb\win64" -I"csdk\include" -I"csdk\src" `
-o build-artifacts\mag160c_demo3.exe csdk\tools\mag160c_demo3.c `
csdk\src\mag160c_display.c csdk\src\mag160c_error.c `
csdk\third_party\libusb\win64\libusb-1.0.x64.a -lgdi32 -luser32
# 官方抓帧工具
gcc -O2 -w -o build-artifacts\tsdk_pair3.exe csdk\tools\tsdk_pair3.c
```
libusb 依赖:`csdk/third_party/libusb/win64/`(头文件 + DLL + MinGW 导入库)。
### 方式 BCMake(有 CMake 时)
```powershell
cmake -B build -S csdk
cmake --build build
ctest --test-dir build
```
无 libusb-1.0 时,IR 会话 API 返回 `MAG160C_ERR_NOT_SUPPORTED`;纯计算
(帧解析、温度、TCM)和对应测试无依赖可跑。
## 快速开始
### 1. 连接并启动(核心 API 流程)
```c
#include <mag160c/mag160c.h>
#include <mag160c/mag160c_display.h>
static void on_frame(uint32_t idx, const uint8_t *data, size_t len, void *user) {
/* data: 完整帧(0x1c 头 + 像素)。用 mag160c_frame_parse 解析。 */
mag160c_frame_header_t hdr;
const uint16_t *pixels;
if (mag160c_frame_parse(data, len, &hdr, &pixels) == MAG160C_OK && hdr.frame_type == 0)
; /* pixels[19200] 小端 uint16160×120 */
}
int main(void) {
mag160c_ctx_t *ctx = NULL;
mag160c_ir_t *ir = NULL;
mag160c_init(&ctx);
mag160c_ir_open(ctx, &ir); /* 自动找 VID 0x833cconfig 2interface 0 */
mag160c_ir_prepare(ir); /* 66b/66c/66f + FFC(0)x2 + 300ms */
mag160c_ir_set_frame_callback(ir, on_frame, NULL);
/* 官方 FFC 节律(周期 1800 帧 / 间隔 9),保持 type=0 流稳定 */
static mag160c_ffc_scheduler_t sched;
mag160c_ffc_scheduler_init(&sched, 1800, 9);
mag160c_ir_set_ffc_scheduler(ir, &sched, 0);
mag160c_ir_start(ir); /* 线程收帧 + 0x6bb6b673 */
/* ... 收帧 / 读温度 ... */
int32_t temp_mc = 0;
mag160c_ir_read_temperature(ir, 80, 60, &temp_mc);
mag160c_ir_stop(ir);
mag160c_ir_close(ir);
mag160c_shutdown(ctx);
return 0;
}
```
### 2. 关键 API
| API | 说明 |
|---|---|
| `mag160c_ir_open/close` | USB 设备会话 |
| `mag160c_ir_prepare` | 官方初始化命令序列 |
| `mag160c_ir_start/stop` | 起停流(0x6bb6b673 / 0x6bb6b674|
| `mag160c_ir_trigger_ffc(param)` | 手动 FFC0 或 1|
| `mag160c_ir_set_ffc_scheduler` | 挂官方节律 FFC 调度器 |
| `mag160c_ir_set_frame_callback` | 每帧回调(解析后数据)|
| `mag160c_ir_read_temperature(x,y,&t)` | 探针温度(毫摄氏度×100|
| `mag160c_frame_parse` | 纯解析:marker/计数/类型/像素指针 |
| `mag160c_frame_stream_*` | 流组装器(乱序/分包恢复)|
| `mag160c_temp_calibrate` | 官方逐像素分段线性校准(NUC 温度域)|
| `mag160c_temp_convert_response` | 自动增益线性换算 |
| `mag160c_temp_t2e_interp` | T2E 曲线 Q13 插值 |
| `mag160c_tcm_*` | TCM 板 FTDICommand 0x7e 帧(旋转/指示灯)|
错误码域 `mag160c_error_t` 与官方 errno 域 `0xE4AE0001..` 对齐;
`mag160c_last_error()` 取线程局部最近错误字符串。
### 3. CLI 用法(mag160c_cli.exe,无硬件可跑纯计算)
```powershell
build-artifacts\mag160c_cli.exe ir-info # 枚举/信息
build-artifacts\mag160c_cli.exe frame-test # 帧解析自测
build-artifacts\mag160c_cli.exe temp-test # 温度换算自测
build-artifacts\mag160c_cli.exe tcm-rotate 5 # TCM 旋转指令编码
build-artifacts\mag160c_cli.exe tcm-light green blink # TCM 指示灯指令编码
```
### 4. 主程序 demo3(官方渲染管线复刻)
`tools/mag160c_demo3.c` 是当前维护的 Windows 直连演示/研究程序,逐像素复刻
CoreSDKLib.dll 的完整链路:
```
USB帧(type=0) → 快门提取(帧尾字) → FFC状态机(0x9ee0)
→ 端点选择+Q12插值(0x16ae0/0x16dd0/0x16f10, 快门驱动)
→ ref = FFC窗口4个type=1帧均值(0x41ee0 mode=4)
→ NUC查表(0x17200) → 盲元补偿(0x17330, 32条固定记录)
→ 统计+窗口(0x10780/0x109c0, half=312) → LUT1024重建(0x11ee0)
→ 灰度+2x升采样(0x19740) → 官方调色板
```
运行(需要 `build-artifacts/` 下的 DDT 表文件):
```powershell
Stop-Process -Name mag160c_demo3 -Force -ErrorAction SilentlyContinue
Start-Process "C:\Project\MAG160C\build-artifacts\mag160c_demo3.exe" -WorkingDirectory "C:\Project\MAG160C\build-artifacts"
```
依赖文件(放 exe 同目录):
| 文件 | 来源 |
|---|---|
| `mag160c_official.ddt` | 官方 DDT 校准文件(`%TEMP%\Core<序列号>` 副本)|
| `mag160c_official_nuc_gain.bin` | 官方 NUC gain/off 表(历史抓取,备用)|
| `mag160c_official_nuc_thr.bin` | 官方 NUC 阈值表(历史抓取,备用)|
| `libusb-1.0.dll` | libusb 运行库 |
验证状态(2026-08-13):
- NUC+盲元 与官方同帧抓帧逐像素 0/19200 误差
- 阈值/gain 插值 0 误差;2x 升采样 0/76800 误差;窗口公式与官方一致
- 同静态场景 gray 直方图与官方相关性 0.92(跨会话)
- 输出日志:`demo3_diag.txt`(每帧统计)、`demo3_ffc.txt`FFC 事件)、
`demo3_auto_*.bmp`(每 30 帧快照)
### 5. 官方抓帧工具(tsdk_pair2 / tsdk_pair3
用途:对照验证 demo3 与官方管线。先停 demo3,再运行(同一设备独占):
```powershell
# tsdk_pair2:官方 ThermalSDK 同帧抓帧(gray/rgb/raw/ref/f20/tables/win
& build-artifacts\tsdk_pair2_fixed.exe C:\Project\MAG160C\analysis\pairs_xxx 12 6000
# tsdk_pair3:增强采集(+ 完整端点表/盲元记录/shutter/h1024/cdf/DDT 复制)
& build-artifacts\tsdk_pair3.exe C:\Project\MAG160C\analysis\pairs_xxx 8 6000
# 注意:config.txt 和 pair_*.meta/win 写在进程 CWD,跑完移回输出目录
```
参数:`<输出目录> <抓帧对数> <官方SDK初始化等待ms>`
若报 "no channel":停止所有程序后重新插拔 USB。
## 测试
```powershell
# 无硬件验证(纯计算)
build-artifacts\csdk_test_frame.exe
build-artifacts\csdk_test_temp.exe
build-artifacts\csdk_test_tcm.exe
build-artifacts\csdk_test_api.exe
build-artifacts\csdk_test_display.exe
```
## 协议要点(详见 analysis/protocol_spec.md
- 端点:EP0x03 命令 OUT / 0x82 响应 IN / 0x81 帧流 IN / 0x84 大块读 IN
- 命令 4 字节 `{magic}`,仅 FFC(0x6bb6b672) 用 8 字节 `{magic, param}`
- 帧:`0x1bb1b11b | counter | len | type(0/1) | ... | 像素 u16 LE | 0x1bb1b11c`
- 快门(设备温度代理)= 帧尾字 `frame[len+0x24]`width=160 时)
- 温度:`temp_mC = T2E[3*nuc - C]`C≈5797(会话相关)
## 文档索引
| 文档 | 内容 |
|---|---|
| `../analysis/protocol_spec.md` | USB 协议/帧/命令/温度完整规格 |
| `../analysis/reverse_20260813_full.md` | 官方管线 Ghidra 全量逆向 + 鬼影根因 |
| `../analysis/session_state.md` | 当前会话状态/恢复点(心跳)|
| `../交接_完整逆向工程说明_20260811.md` | 项目总交接(目录/环境/历史)|
| `WINDOWS_TESTING.md` | Windows 抓包与硬件测试指南 |
| `legacy/` | 历史工具源码归档(早期探索,功能已被现工具取代)|