Knight1/vanmoof-canbus
GitHub: Knight1/vanmoof-canbus
用于解析 VanMoof SA5 及以上型号电动自行车 CAN Bus 通信的 Go 语言工具,支持 CBOR 多帧消息重组和协议解码。
Stars: 1 | Forks: 0
# CAN Bus 解析器
一个用于解析和解码 VanMoof SA5 及后续型号自行车 CAN Bus 帧的 Go 应用程序。
该工具读取 CSV 和 candump 格式的 CAN 帧数据,重组多帧 CBOR 消息,并根据 VanMoof 协议规范解码 CBOR 编码的载荷。
## 前置条件
- Go 1.24 或更高版本
## 安装
```
go build -v -ldflags="-w -s" -mod=vendor ./...
```
## 使用方法
解析 CAN dump 文件:
```
./canbus < input.log
```
### 参数标志
| 标志 | 描述 |
|---|---|
| `--version` | 显示版本信息 |
| `--devices` | 打印 SA5 CAN Bus 设备表并退出 |
| `--protocol` | 打印 CAN Bus 协议摘要并退出 |
| `--canids` | 打印所有 CAN ID 并退出 |
| `--decode-id HEX` | 解码指定 CAN ID (例如 `018F808F`) |
| `--group-by-id` | 按 CAN ID 分组帧,按时间戳排序 |
| `--unaccounted-only` | 仅显示非 CBOR 或心跳帧 |
| `--hide-unaccounted` | 隐藏未 accounted 帧 |
| `--hide-accounted` | 隐藏 CBOR 和心跳帧 |
| `--compare FILE...` | 比较多个文件中的未 accounted 帧 |
### 示例
```
# Decode a capture
./canbus < dumps/bikelocked.log
# Show only unrecognized frames
./canbus --unaccounted-only < dumps/startup_from_app.log
# Print the device address table
./canbus --devices
# Print the full protocol reference
./canbus --protocol
# List all CAN IDs
./canbus --canids
# Decode a specific CAN ID
./canbus --decode-id 018F808F
# Compare unaccounted frames across captures
./canbus --compare dumps/bikelocked.log dumps/startup_from_app.log
```
## VanMoof SA5 CAN Bus 协议
### 总线配置
| 参数 | 值 |
|---|---|
| 速度 | 1 Mbps |
| 控制器 | Bosch M_CAN (支持 CAN FD,用作经典 CAN) |
| M_CAN 基址 | 0x4009D000 |
| 硬件过滤器 | 无 (混杂模式) |
| 帧类型 | 29 位扩展 CAN ID |
#### DP=0: 特殊用途消息
| 模式 | 名称 | 描述 |
|---|---|---|
| `0x00{PF}8887` | 灯光配对同步 | 每个设备发送一个;b1=0x88(尾灯), b0=0x87(前灯) |
| `0x00{PF}0182` | BLE 命令类型 1 | 发往 BLE 模块的命令 |
| `0x00{PF}0382` | BLE 命令类型 3 | 发往 BLE 模块的命令 |
| `0x00{PF}{cmd}{target_pfsa}` | 设备命令 | DP=0 命令,通过 PF/SA 值发往特定设备 |
### CBOR 成帧协议
VanMoof CAN Bus 使用一种成帧机制,通过 8 字节的 CAN 帧传输多帧 CBOR 编码消息。
#### 头字节结构
每个 CAN 帧的第一个字节是头字节。高半字节决定帧类型:
| 头范围 | 类型 | 描述 |
|---|---|---|
| `0xAx` (0xA0-0xAF) | **START** | 开始一个新的 CBOR 消息 |
| `0x1x` (0x10-0x1F) | **CONTINUATION** | 当前消息的延续 |
| `0x8x` / `0x9x` | **DATA** | 原始数据帧 (非 CBOR) |
| `0x0x` (0x00) | **STATUS/HEARTBEAT** | 保活或状态 (ID 以 `01111` 开头,全零载荷) |
#### 解码步骤
1. **检测** 帧类型,通过检查头字节的高半字节
2. **提取** 载荷:移除头字节 (第一个字节),保留剩余的 7 个字节
3. **累积**:START 帧初始化缓冲区;CONTINUATION 帧追加数据
4. **解码** 当解析器成功时解码完整的 CBOR 消息
5. **显示** 递归显示解码后的结构
### 总线拓扑
```
Main CAN Bus (1 Mbps, no hardware filters)
|
|-- imx8_bridge (0x80) Central gateway to i.MX8 SoC
|-- ble (0x82) Bluetooth Low Energy module
|-- modem (0x83) Cellular connectivity
|-- motor_sensor (0x84) Speed/cadence sensing
|-- elock (0x85) Electronic lock mechanism
|-- user_ecu (0x86) Main user controller
|-- frontlight (0x87) Front light controller
|-- rearlight (0x88) Rear light controller
|-- eshifter (0x91) Electronic gear shifter
|-- power_pedal (0x92) Pedal assist / torque sensor
|-- motor_control (0x93) Motor controller (non-ARM MCU)
+-- power_control (??) Power management
Charger CAN Bus (separate segment)
|-- charger (0x70) Liteon charger controller
+-- charger_target (0x8D) Battery BMS / power delivery unit
```
### 通信矩阵
具有完全总线访问权限的设备(11 个处理程序):motor_sensor, elock, user_ecu, frontlight, rearlight, eshifter, power_pedal
具有有限总线访问权限的设备(7 个处理程序):imx8_bridge, power_control
充电器在单独的 CAN Bus 段上运行,仅与设备 0x8D 通信。
## 捕获 CAN Bus 数据
### 硬件
你需要一个支持 **1 Mbps** 和 **29 位扩展 ID** 的 CAN Bus 适配器。推荐使用 **MCP2518FD** (CAN FD SPI 控制器) —— 通常可在 "CANBed FD"、CANable、Adafruit MCP2518FD 等分线板上找到。简单的 MCP2515 也可以工作,因为总线使用经典 CAN 成帧,但你需要 PCB 上有特定的晶振(至少 20MHz)。大多数 AliExpress PCB 使用的频率要低得多,无法在总线上达到 1Mbits。
**连接到自行车的接线:**
将适配器的 CAN_H 和 CAN_L 连接到自行车的 CAN Bus。一个方便的接入点是在踏板附近自行车右侧盖子下的隐藏连接器。
传言说这过去/现在是用于移动电源的。但我用它来连接自行车而无需拆卸任何东西。
当你只将一个设备(如电池)直接连接到适配器时,需要一个终端电阻。
### Linux / Raspberry Pi
MCP2518FD 通过 SPI 配合 `mcp251xfd` 内核驱动工作。在 Raspberry Pi 上,添加到 `/boot/config.txt`:
```
dtoverlay=mcp251xfd,spi0-0,oscillator=40000000,interrupt=25
```
然后启动接口并捕获:
```
# install can tools
sudo apt install can-utils
# Set up the CAN interface at 1 Mbps
sudo ip link set can0 up type can bitrate 1000000
# Capture to file using candump (from can-utils)
candump -L can0 > capture.log
# Or capture with timestamps
candump -ta can0 > capture.log
```
标签:CAN_dump, CAN总线, CBOR, EVTX分析, Go语言, SA5, VanMoof, 二进制发布, 云资产清单, 交通载具, 嵌入式系统, 开源工具, 数据解码, 日志审计, 物联网, 电动自行车, 硬件黑客, 程序破解, 逆向工程