creativeux/goaldl
GitHub: creativeux/goaldl
一款用 Go 语言编写的跨平台诊断扫描仪与数据记录器,通过 USB 串口适配器解码通用汽车 pre-OBD2 的 160 波特 ALDL 协议数据流。
Stars: 0 | Forks: 0
# goaldl
[](https://github.com/creativeux/goaldl/actions/workflows/ci.yml)
一个跨平台的 Go 扫描仪和数据记录器,用于 GM 的 160-baud ALDL (Assembly
Line Diagnostic Link) 协议 —— 这是 GM ECM 使用的 pre-OBD2 诊断数据流。
主要目标:**GM 1227747** (A033 TBI, '86–'88 4.3/5.0/5.7L)。
**状态:** 已在真实硬件上正常工作并验证。字节值解码器
通过普通的 USB 串口适配器读取 160 波特流,并生成
正确的帧 —— 已通过 WinALDL 基准日志和一次真实驾驶
捕获记录进行验证(在全工况范围内 635/635 帧具有匹配的 PROM ID)。

## 工作原理简介
ALDL 线路空闲时为高电平,并将每个位编码为低电平脉冲的*宽度*(短脉冲 ≈ 逻辑 0,长脉冲 ≈ 逻辑 1)。带有反相功能的接口线缆将此信号馈送到 PC UART,后者精确地为每个 ALDL 位组帧为**一个字节** —— 因此解码只需读取字节*值*,而无需依赖主机端定时(USB 使得这种定时不可靠)。在 4800 波特率下,短脉冲到达时为 `0xFE`,长脉冲为 `0x00`;连续的九个 1 位是 `0x1FF` 同步标志,用于界定 20 字节的帧。完整的模型以及发展历史记录在 [`CLAUDE.md`](CLAUDE.md) 中;具体实现位于 `pkg/decoder/`。
## 安装
```
go build ./cmd/goaldl # build
go run ./cmd/goaldl # or run directly; prints available commands
```
或者从 [Releases](https://github.com/creativeux/goaldl/releases) 页面为您的平台下载预编译的二进制文件。
### macOS:允许下载的二进制文件
预编译的二进制文件尚未进行代码签名或公证,因此 macOS Gatekeeper 会阻止刚下载的副本 —— *“Apple 无法验证‘goaldl’是否不含恶意软件……”*。这是 macOS 对任何通过浏览器下载的文件添加的隔离标志,而不是二进制文件本身的问题。只需清除一次该标志,然后运行:
```
xattr -d com.apple.quarantine ./goaldl # or: xattr -cr ./goaldl
./goaldl
```
或者,在 Finder 中右键单击该二进制文件并选择**打开**,或者在启动被阻止后,打开**系统设置 → 隐私与安全性**,然后点击**仍要打开**。从源码构建(`go build ./cmd/goaldl`)或使用 `go install` 可以完全避免此问题,因为在本地构建的二进制文件永远不会被隔离。
## 平台支持
goaldl 是纯 Go 实现(不使用 CGO),因此一套代码库即可构建以下所有平台。完整的分层矩阵(包括嵌入式情况)位于 [`product-knowledge/standards/release/platform-support.md`](product-knowledge/standards/release/platform-support.md) 中。
**核心支持(已构建、测试和支持):**
| 平台 | 架构 | 最低操作系统要求 | 串口适配器驱动 |
|---|---|---|---|
| macOS | Apple Silicon + Intel | macOS 12 | App Store 中的 Prolific "PL2303 Serial" 应用(2012 年之前/山寨的 PL2303HXA 芯片被驱动屏蔽);FTDI 开箱即用 |
| Windows | x64 | Windows 10 | 通过 Windows Update 自动安装 |
| Linux | x64, arm64 | 内核 ≥ 3.2(静态二进制文件 —— 支持 glibc、musl/Alpine 等任何环境) | `pl2303` 包含在每个主流内核中;将您自己添加到 `dialout` (Debian/Ubuntu/Pi OS) 或 `uucp` (Arch) 组中即可打开端口 |
**尽力支持(每次发布都会附带二进制文件,但未经人工测试):**
Raspberry Pi 3/4/5 使用标准的 linux-arm64 构建(TUI 可通过 SSH 运行);linux-armv6 构建覆盖了运行 32 位 Pi OS 的 Pi Zero/1/2。Windows arm64 也会发布二进制文件,但 Prolific 的 ARM64 驱动支持并不完善 —— 建议在这些平台上使用 FTDI 适配器。FreeBSD amd64 可通过内置的 `uplcom(4)` 驱动程序运行(端口显示为 `/dev/cuaU*`)。
微控制器(通过 TinyGo 支持的 Arduino 级开发板、Particle)不是发布目标 —— 有关解码器核心的 TinyGo 移植需要什么条件,请参阅矩阵文档。
## 发布与版本控制
每个二进制文件都会自检其构建信息:`goaldl version`(或 `--version`)。正式发布的构建包含语义版本号 + 提交记录;直接从源码 `go build` 则会回退到 Go 工具链注入的 VCS 版本号。
版本控制基于 [Conventional Commits](https://www.conventionalcommits.org) 自动化处理:
- 在 `main` 分支上使用 `feat:` / `fix:` / `feat!:`(破坏性更新)前缀进行提交。
- [release-please](https://github.com/googleapis/release-please) 会保持一个开启状态的
“release PR”,用于提升版本号并更新 `CHANGELOG.md`。合并该 PR
会自动打上 `vX.Y.Z` 标签并创建一个 GitHub Release。
- 然后 [GoReleaser](https://goreleaser.com) 构建 macOS/Linux/Windows
(amd64 + arm64)二进制文件 —— 版本号通过 ldflags 嵌入 —— 并将它们附加到
该发布中。使用 `goreleaser release --snapshot --clean` 在本地进行试运行。
在 1.0 版本之前,破坏性更新会提升次要版本号(根据配置永远不会是 1.0)。
## 命令
`goaldl` 本身就是一个**交互式仪表板** —— 可以在不同的标签页间切换传感器、BLM
网格和原始帧视图,支持实时查看或回放捕获的数据。将命令词作为
第一个参数可运行该脚本命令。
```
# The dashboard (default) — live from the ECM, or replaying a capture
goaldl -p /dev/cu.usbserial-10
goaldl drive_4800.raw # replay (-speed N to scrub)
goaldl # auto-connects if one USB serial port is present
# keys: 1-3 / tab switch views · q quit
# Scripting / headless commands (top-level command words):
goaldl ports # find the adapter (name drifts; check before -p)
# Capture raw bytes at the car, then work offline
goaldl record -p /dev/cu.usbserial-10 -t 60 -o drive_4800.raw
goaldl decode drive_4800.raw -o frames.csv
# Streaming (non-interactive) sensor table; optionally record raw + log CSV
goaldl monitor -p /dev/cu.usbserial-10 -o session.raw -csv live.csv
goaldl monitor drive_4800.raw # replay as a streaming table
# BLM fuel-trim table (where the tune runs rich/lean)
goaldl blm drive_4800.raw -o correction.csv
# Synthetic capture (no hardware); list ECMs
goaldl simulate -n 10 && goaldl decode aldl_sim_4800.raw
goaldl ecms
```
推荐的工作流程是**先记录,后离线分析**:在汽车旁捕获一次原始字节(`goaldl record`),然后根据需要随时针对该文件重新运行仪表板或 `decode`/`blm`。
## BLM 燃油微调调试
`blm` 命令可将一次驾驶捕获记录转换为燃油微调映射图 —— 这是一张展示基础调校在整个 RPM 和负荷范围内偏浓或偏稀位置的图表。它从每一帧中读取 Block
Learn Multiplier (BLM,即 ECM 的长期燃油微调),并将其划分到 RPM × MAP 网格中。
**解读 BLM:128 为中性。** 低于 128 表示 ECM 正在*减少*燃油,因为混合气偏浓(该处的基础调校燃油过多);高于 128 表示正在*增加*燃油,因为混合气偏稀。每个单元格报告的**修正系数**为 `avg_BLM / 128` —— 将该单元格的基础 VE/燃油乘以此系数,即可使 ECM
恢复到 128。
仅记录处于闭环且启用了 block-learn 的帧 —— BLM 在全油门、减速或预热期间是冻结且无意义的,因此这些帧会被跳过。在收集到足够的读数之前,单元格也是不可信的(默认为 4;BLM 会波动,因此一两个样本存在噪声)。低于该阈值时,单元格的修正值将保持为 `1.000`(无变化),并且在实时视图中,在数据累积期间会以暗色显示。
```
# Offline: build the tables from a capture, write the correction grid to CSV
goaldl blm drive_4800.raw -o correction.csv
goaldl blm drive_4800.raw -min 3 # trust a cell at 3 samples (WinALDL-like)
# Live: watch each cell fill and settle as you drive — in the dashboard's BLM
# tab, or the streaming grid (· = empty, dim = accumulating, solid = trusted)
goaldl -p /dev/cu.usbserial-10 # dashboard, press 2
goaldl monitor -p /dev/cu.usbserial-10 -blm -o session.raw # streaming grid
```
`blm` 打印三个表格 —— Samples、Wide Average BLM 和 Correction factor —— 与 `data/20250601_162123_BLM.txt` 的格式相匹配。MAP→kPa 轴使用标准的 GM 1-bar 传输函数(`pkg/ecm/fueltrim.go`);它仅影响读数落入的列,而不影响 BLM 计算。
## 项目布局
```
cmd/goaldl/ binary: main.go (dispatch: command word → that command,
else → dashboard) + tui.go + capture/monitor/blm/csv
pkg/decoder/ The decoder (byte-value state machine) + synthetic encoder + tests
testdata/ Real raw captures + golden frame dumps — the root of the test suite
pkg/stream/ Core engine: Session → Snapshot (the reusable API any front-end drives)
+ Provider abstraction (replay/serial) + terminal view builders
pkg/blm/ BLM fuel-trim accumulator (RPM × MAP grid, averages, correction)
pkg/ecm/ ECM definitions, frame parsing, and fuel-trim extraction (GM 1227747 per A033.ads)
pkg/serial/ Thin serial-port wrapper (open/read/flush/list) — no decoding
pkg/aldl/ Shared Frame type
pkg/errors/ Error types
data/ Reference captures and A033.ads ECM definition
docs/history/ Superseded debugging notes, kept for context
```
## 测试
```
go test ./...
```
测试套件根植于 `pkg/decoder/testdata/` 下的真实捕获记录:
`TestDecodeRealCapture` 断言了怠速和驾驶记录的精确解码统计信息和 100% 的 PROM-ID 匹配,而 `TestGolden` 锁定了精确的解码帧字节数据。在有意修改解码器之后,请使用以下命令重新生成 golden 文件:
```
go test ./pkg/decoder -run TestGolden -update # then review the diff before committing
```
## 数据策略
解码器是一个忠实的传输层:它**不**进行任何合理性过滤、
异常值剔除或平滑处理,而是按原样输出每一个结构上对齐的帧(包括各种瑕疵)。质量信号伴随数据一起提供(例如 PROM-ID 匹配);数据质量决策属于下游消费者的范畴,可以在那里进行调整或禁用。
## 硬件
- 一根 USB 转 ALDL 线缆/适配器(连接到 UART RX
线路上带有反相功能的电平转换器)。已在 macOS 上使用 Prolific PL2303 测试过;真正的 FTDI FT232R
是一个不错的替代方案(在 macOS 上支持原生驱动)。有关
驱动说明和板载 MCU 选项,请参阅 [`CLAUDE.md`](CLAUDE.md)。
- 一辆带有 ALDL 端口的兼容 GM 车辆(通常位于仪表板下方)。
## 参考
- ALDL 160 波特规范:
- 使用 Teensy 解码 GM ALDL:
- A033.ads ECM 定义:`data/A033.ads`
## 许可证
GPL-3.0(保持与原始 rustaldl 项目的兼容性)。
标签:EVTX分析, Go语言, OBD诊断工具, 串口通信, 命令控制, 嵌入式硬件, 数据采集, 日志审计, 程序破解, 车载诊断