diff --git a/resources/examples/can_tp/readme.zh.md b/resources/examples/can_tp/readme.zh.md index efa5b423..9997848e 100644 --- a/resources/examples/can_tp/readme.zh.md +++ b/resources/examples/can_tp/readme.zh.md @@ -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 @@ -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' @@ -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.