Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 37 additions & 37 deletions resources/examples/can_tp/readme.zh.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
# CAN-TP 示例
# CAN-TP Example

演示 ISO 15765-2(CAN 传输层协议)的 Worker API:`CanTpCreateConnection` / `CanTpSendData` / `CanTpRecvData`。无需真实硬件——两个节点运行在同一个虚拟 CAN 总线上即可。
Demonstrates the `CanTpCreateConnection` / `CanTpSendData` / `CanTpRecvData` worker API for ISO 15765-2 (CAN Transport Protocol) communication. No hardware required — both nodes run on a single virtual CAN bus.

## 概述
## Overview

- **节点 1 (tester.ts)**:使用 `CanTp*` API 发送请求、接收响应。启动时自动执行四个测试,覆盖单帧和多帧场景,最大 500 字节。
- **节点 2 (ecu.ts)**:用 `Util.OnCan` + `output()` 实现的模拟 ECU,手动处理 ISO 15765-2 SF / FF / CF / FC 帧,返回正响应(`service_id + 0x40`,其余字节原样)。
- **设备**:SIMULATE_0(虚拟 CAN 总线,无需硬件)
- **Node 1 (tester.ts)**: Uses the `CanTp*` API to send requests and receive responses. Runs four tests on startup covering single-frame and multi-frame scenarios up to 500 bytes.
- **Node 2 (ecu.ts)**: Simulated ECU implemented with `Util.OnCan` + `output()`. Handles ISO 15765-2 SF / FF / CF / FC frames manually and echoes back a positive response (`service_id + 0x40`).
- **Device**: SIMULATE_0 (virtual CAN bus — no hardware needed)

## 地址配置
## Addressing

| 参数 | Tester | ECU |
|------|--------|-----|
| TX ID | `0x7E0` | `0x7E8` |
| RX ID | `0x7E8` | `0x7E0` |
| 寻址模式 | Normal | Normal |
| Parameter | Tester | ECU |
| ---------- | ------- | ------- |
| TX ID | `0x7E0` | `0x7E8` |
| RX ID | `0x7E8` | `0x7E0` |
| Addressing | Normal | Normal |

## 测试项
## Tests

| # | 数据长度 | 帧类型 | 通过条件 |
|---|---------|--------|---------|
| 1 | 2 B | SF TX → SF RX | `resp[0] == 0x50``resp.length == 2` |
| 2 | 8 B | MF TX → MF RX | `resp[0] == 0x62``resp.length == 8` |
| 3 | 20 B | MF TX → MF RX | `resp[0] == 0x76``resp.length == 20` |
| 4 | 500 B | MF TX → MF RX | `resp[0] == 0x76``resp.length == 500` |
| # | Payload | Frame type | Pass condition |
| - | ------- | ------------- | --------------------------------------- |
| 1 | 2 B | SF TX → SF RX | `resp[0] == 0x50`, `resp.length == 2` |
| 2 | 8 B | MF TX → MF RX | `resp[0] == 0x62`, `resp.length == 8` |
| 3 | 20 B | MF TX → MF RX | `resp[0] == 0x76`, `resp.length == 20` |
| 4 | 500 B | MF TX → MF RX | `resp[0] == 0x76`, `resp.length == 500` |

## 如何运行
## How to Run

1. 在 EcuBus-Pro 中打开 `can_tp.ecb`
2. 启动工程,两个节点自动运行
3. 查看 Tester 节点日志
1. Open `can_tp.ecb` in EcuBus-Pro
2. Start the project — both nodes launch automatically
3. Check the Tester log for pass / fail results

预期 Tester 输出:
Expected tester output:

```
[Tester] Connection ready
Expand Down Expand Up @@ -59,9 +59,9 @@
[Tester] Done 4/4 passed
```

## 代码要点
## Code Highlights

### Tester — 创建连接并收发数据
### Tester — create connection and send/receive

```typescript
import { CanTpCreateConnection, CanTpSendData, CanTpRecvData, CanTpCloseConnection } from 'ECB'
Expand All @@ -83,38 +83,38 @@ const { data } = await CanTpRecvData(handle, 2000)
await CanTpCloseConnection(handle)
```

### ECU — Util.OnCan 处理原始帧
### ECU — raw frame handler with Util.OnCan

```typescript
Util.OnCan(0x7E0, (msg) => {
const d = Array.from(msg.data)
const frameType = (d[0] >> 4) & 0x0f

if (frameType === 0) { // SF — 直接回复
if (frameType === 0) { // SF — respond immediately
respond(d.slice(1, 1 + (d[0] & 0x0f)))
} else if (frameType === 1) { // FF — FC
} else if (frameType === 1) { // FF — send FC
rxState = { totalLen: ((d[0] & 0xf) << 8) | d[1], buf: [...d.slice(2)], expectedSN: 1 }
sendRaw([0x30, 0x00, 0x00])
} else if (frameType === 2) { // CF — 累积,完整后回复
} else if (frameType === 2) { // CF — accumulate, respond when complete
rxState!.buf.push(...d.slice(1))
if (rxState!.buf.length >= rxState!.totalLen) respond(rxState!.buf)
} else if (frameType === 3) { // FC — 发送剩余 CF
} else if (frameType === 3) { // FC — send remaining CFs
while (txState!.offset < txState!.data.length) { ... }
}
})
```

## 文件结构
## File Structure

```
can_tp/
├── can_tp.ecb # 工程配置(SIMULATE_0,两个节点)
├── tester.ts # 节点 1 — CanTp* API 演示
├── ecu.ts # 节点 2 — Util.OnCan + output() 模拟 ECU
├── can_tp.ecb # Project config (SIMULATE_0, two nodes)
├── tester.ts # Node 1 — CanTp* API demo
├── ecu.ts # Node 2 — Util.OnCan + output() ECU simulator
├── readme.md
└── readme.zh.md
```

## 真实硬件
## Real Hardware

SIMULATE_0 替换为真实 CAN 设备。双节点在同一物理总线上通信时,两个通道必须能互相 ACK(背靠背连接的两个通道,或总线上接有真实 ECU)。详见 [EcuBus-Pro 文档](https://ecubus.org)
Replace `SIMULATE_0` with a real CAN device. For a two-node setup on the same physical bus, both channels must be able to ACK each other (separate channels connected back-to-back, or a real ECU on the bus). See the [EcuBus-Pro documentation](https://ecubus.org) for hardware configuration.
Loading