Files
DCU_APP/communication_ids.html
T
cbb b171767023 feat(ethercat): 添加EtherCAT从站功能支持并优化同步机制
- 添加CAN反馈和ID快照SPI命令文件
- 移除EXMC组件依赖,精简项目配置
- 添加RAM函数段链接脚本,优化Flash等待周期抖动
- 实现EscExmcBus类,提供16位并行总线访问LAN9252
- 实现EscLan9252驱动,支持寄存器和PDI内存访问
- 实现EthercatSlave类,采用三缓冲机制进行PDO数据交换
- 实现EthercatSync同步管理,支持SYNC0/SYNC1中断和定时器模式
- 添加ISR执行时间统计和诊断功能
- 分离周期路径和事件路径通知机制,避免RMW竞态
2026-06-29 01:51:02 +08:00

339 lines
20 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>DCU_APP SPI 通信 ID 参考</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
:root{--bg:#f6f8fb;--card:#fff;--line:#dfe3ea;--muted:#6b7280;--text:#111827}
*{box-sizing:border-box}
body{margin:0;padding:28px 20px 48px;background:var(--bg);color:var(--text);font-family:"Segoe UI","Microsoft YaHei","PingFang SC",Arial,sans-serif;line-height:1.7}
.page{max-width:1080px;margin:0 auto}
h1{margin:0 0 8px;font-size:22px}
.muted{margin:0 0 22px;color:var(--muted);font-size:13px}
.stack{display:grid;grid-template-columns:1fr;gap:22px}
.card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:18px 20px;box-shadow:0 1px 2px rgba(16,24,40,.04)}
h2{margin:0 0 8px;font-size:18px}
.sub{margin:0 0 14px;color:var(--muted);font-size:12px}
details{border:1px solid var(--line);border-radius:10px;background:#fff;margin-top:12px}
summary{cursor:pointer;padding:14px 16px;font-weight:600}
.inside{padding:0 16px 16px}
table{width:100%;border-collapse:collapse;margin:10px 0 16px;font-size:14px}
th,td{border:1px solid var(--line);padding:10px 12px;vertical-align:top}
th{background:#f1f4f8;text-align:left;width:180px}
.note{background:#f8fafc;border:1px solid var(--line);border-radius:10px;padding:12px 14px;color:#374151;font-size:13px}
code{background:#f8fafc;padding:1px 4px;border-radius:4px}
.diagram{display:grid;grid-template-columns:1fr;gap:14px;margin:12px 0 16px}
.cell{flex:0 1 150px;min-width:120px;border:1px solid var(--line);border-radius:10px;background:#fff;overflow:hidden;page-break-inside:avoid;break-inside:avoid}
.row{display:flex;flex-wrap:wrap;gap:12px;margin:10px 0 14px;align-items:stretch}
.cell{border:1px solid var(--line);border-radius:10px;background:#fff;overflow:hidden}
.cell .top{padding:8px 10px;font-weight:700;background:#eef2f8;text-align:center;font-size:14px}
.cell .mid{padding:8px 10px;text-align:center;font-size:13px;color:#111}
.cell .bot{padding:8px 10px;border-top:1px solid var(--line);color:#374151;font-size:12px;text-align:center}
.cell.error .top{background:#fee2e2}
.cell.ok .top{background:#dcfce7}
.cell.info .top{background:#dbeafe}
.foot{margin-top:22px;color:var(--muted);font-size:12px}
.section-title{margin:18px 0 8px;font-size:14px;font-weight:600}
</style>
</head>
<body>
<div class="page">
<h1>DCU_APP SPI 通信 ID(按注册命令展开,三行直观图)</h1>
<p class="muted">按 <code>device/spi/app_spi_command.cpp</code> 注册顺序组织;每个命令均可展开查看 payload,并用“序号 / 组合 / 说明”三行显示。</p>
<div class="note" style="margin-bottom:18px">⚠ 单帧 payload 最大 <code>123</code> 字节(<code>kTxBufSize=128</code> - 协议开销 5 字节),超过将被 <code>AppSpiCommand::processCommand()</code> 拒收。</div>
<div class="stack">
<section class="card">
<h2>Boot Request</h2>
<div class="sub">注册函数:<code>registerSpiBootRequestCommand</code></div>
<details>
<summary>展开查看 ID / payload / 功能</summary>
<div class="inside">
<table>
<tr><th>命令/响应</th><th>符号</th><th>值</th></tr>
<tr><td>命令帧类型</td><td><code>kTypeBootReq</code></td><td><code>0xB0</code></td></tr>
<tr><td>成功响应</td><td><code>kRspAck</code></td><td><code>0x80</code></td></tr>
</table>
<div class="section-title">payload 直观图</div>
<div class="diagram">
<div class="cell info">
<div class="top">req</div>
<div class="mid">—</div>
<div class="bot">无可扩展 payload 字段</div>
</div>
<div class="cell ok">
<div class="top">ack</div>
<div class="mid">0x80</div>
<div class="bot">成功应答</div>
</div>
</div>
<div class="note">功能:请求进入 Boot 状态,回 ACK。</div>
</div>
</details>
</section>
<section class="card">
<h2>OTA Wait</h2>
<div class="sub">注册函数:<code>registerSpiOtaWaitCommand</code></div>
<details>
<summary>展开查看 ID / payload / 功能</summary>
<div class="inside">
<table>
<tr><th>命令</th><th>符号</th><th>值</th></tr>
<tr><td>OTA 请求</td><td><code>kTypeOtaReq</code></td><td><code>0x01</code></td></tr>
<tr><td>OTA 数据</td><td><code>kTypeOtaData</code></td><td><code>0x02</code></td></tr>
<tr><td>OTA 取消</td><td><code>kTypeOtaCancel</code></td><td><code>0x03</code></td></tr>
<tr><td>响应</td><td><code>kRspWait</code></td><td><code>0x81</code></td></tr>
</table>
<div class="section-title">response payload 直观图</div>
<div class="diagram">
<div class="cell info">
<div class="top">[0]</div>
<div class="mid">0x01</div>
<div class="bot">hint 固定值</div>
</div>
</div>
<div class="note">功能:OTA 占位/流控,占位/流控。</div>
</div>
</details>
</section>
<section class="card">
<h2>App Ping</h2>
<div class="sub">注册函数:<code>registerSpiAppPingCommand</code></div>
<details>
<summary>展开查看 ID / payload / 功能</summary>
<div class="inside">
<table>
<tr><th>命令/响应</th><th>符号</th><th>值</th></tr>
<tr><td>命令帧类型</td><td><code>kTypeAppPing</code></td><td><code>0xA1</code></td></tr>
<tr><td>响应</td><td><code>kRspAck</code></td><td><code>0x80</code></td></tr>
</table>
<div class="section-title">response payload 直观图</div>
<div class="diagram">
<div class="row">
<div class="cell info"><div class="top">[0]</div><div class="mid">0xA1</div><div class="bot">magic</div></div>
<div class="cell info"><div class="top">[1]</div><div class="mid">0x55</div><div class="bot">APP version tag</div></div>
<div class="cell ok"><div class="top">[2..5]</div><div class="mid">APP_VER</div><div class="bot">MAJOR/MINOR/PATCH/BUILD</div></div>
<div class="cell info"><div class="top">[6]</div><div class="mid">0xAA</div><div class="bot">BOOT version tag</div></div>
<div class="cell ok"><div class="top">[7..10]</div><div class="mid">BOOT_VER</div><div class="bot">Boot版本</div></div>
<div class="cell ok"><div class="top">[11..14]</div><div class="mid">uptime</div><div class="bot">运行秒数</div></div>
</div>
</div>
<div class="note">功能:读取版本与 uptime。</div>
</div>
</details>
</section>
<section class="card">
<h2>CAN Bridge</h2>
<div class="sub">注册函数:<code>registerSpiCanBridgeCommand</code></div>
<details>
<summary>展开查看 ID / payload / 功能</summary>
<div class="inside">
<table>
<tr><th>命令/响应</th><th>符号</th><th>值</th></tr>
<tr><td>命令帧类型</td><td><code>kTypeCanSend</code></td><td><code>0xC0</code></td></tr>
<tr><td>成功响应</td><td><code>kRspAck</code></td><td><code>0x80</code></td></tr>
<tr><td>错误响应</td><td><code>kRspError</code></td><td><code>0x82</code></td></tr>
</table>
<div class="section-title">request payload 直观图</div>
<div class="diagram">
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">can_ch</div><div class="bot">通道 0/1/2</div></div>
<div class="cell info"><div class="top">[1..4]</div><div class="mid">can_id</div><div class="bot">CAN ID(32bit)</div></div>
<div class="cell info"><div class="top">[5..N]</div><div class="mid">can_data</div><div class="bot">数据区</div></div>
</div>
</div>
<div class="section-title">response payload 直观图</div>
<div class="diagram">
<div class="row">
<div class="cell ok"><div class="top">ack</div><div class="mid">0x00</div><div class="bot">OK</div></div>
<div class="cell error"><div class="top">err</div><div class="mid">E0/E1/E2</div><div class="bot">短帧/通道/忙</div></div>
</div>
</div>
<div class="note">错误码:<code>E0</code>=payload 不足,<code>E1</code>=通道非法,<code>E2</code>=发送忙/失败。</div>
<div class="note">功能:ESP32 透传 CANFD 发送帧,校验后发送。</div>
</div>
</details>
</section>
<section class="card">
<h2>CAN Feedback (ID Snapshot) / Set Mode</h2>
<div class="sub">注册函数:<code>registerSpiCanFeedbackCommand</code></div>
<details>
<summary>展开查看 ID / payload / 功能</summary>
<div class="inside">
<table>
<tr><th>命令</th><th>符号</th><th>值</th></tr>
<tr><td>反馈查询(分页)</td><td><code>kTypeCanFeedback</code></td><td><code>0xC1</code></td></tr>
<tr><td>模式切换</td><td><code>kTypeCanSetMode</code></td><td><code>0xC2</code></td></tr>
<tr><td>成功响应</td><td><code>kRspAck</code></td><td><code>0x80</code></td></tr>
<tr><td>错误响应</td><td><code>kRspError</code></td><td><code>0x82</code></td></tr>
</table>
<div class="section-title">0xC1 request payload 直观图(分页请求)</div>
<div class="diagram">
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">channel</div><div class="bot">通道 0/1/2</div></div>
<div class="cell ok"><div class="top">[1]</div><div class="mid">page</div><div class="bot">页号 0 或 1</div></div>
</div>
</div>
<div class="section-title">0xC1 response payload 直观图(统计头 + ID 快照条目)</div>
<div class="sub">应答变长,最大 123 字节。固定头 25B + 条目逐条拼接。</div>
<div class="diagram">
<div class="sub" style="font-weight:600;">固定头(25 字节)</div>
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">channel</div><div class="bot">回显通道 0/1/2</div></div>
<div class="cell ok"><div class="top">[1]</div><div class="mid">page</div><div class="bot">回显页号</div></div>
<div class="cell info"><div class="top">[2]</div><div class="mid">total_count</div><div class="bot">ID 条目总数(0~16)</div></div>
<div class="cell info"><div class="top">[3]</div><div class="mid">entry_count</div><div class="bot">本页条目数</div></div>
<div class="cell info"><div class="top">[4]</div><div class="mid">mode</div><div class="bot">当前接收模式</div></div>
</div>
<div class="row">
<div class="cell info"><div class="top">[5..8]</div><div class="mid">snapshot_seq</div><div class="bot">快照序号(LE)</div></div>
<div class="cell info"><div class="top">[9..12]</div><div class="mid">rx_count</div><div class="bot">通道累计接收(LE)</div></div>
<div class="cell info"><div class="top">[13..16]</div><div class="mid">tx_count</div><div class="bot">通道累计发送(LE)</div></div>
<div class="cell info"><div class="top">[17..20]</div><div class="mid">rx_drop_count</div><div class="bot">通道丢帧(LE)</div></div>
<div class="cell info"><div class="top">[21..24]</div><div class="mid">error_count</div><div class="bot">通道错误(LE)</div></div>
</div>
<div class="sub" style="font-weight:600;margin-top:14px;">条目区(从 [25] 开始,逐条拼接,变长)</div>
<div class="row">
<div class="cell ok"><div class="top">[+0..+3]</div><div class="mid">id</div><div class="bot">CAN 报文 ID(LE)</div></div>
<div class="cell info"><div class="top">[+4]</div><div class="mid">dlc</div><div class="bot">数据长度 1~64</div></div>
<div class="cell info"><div class="top">[+5]</div><div class="mid">flags</div><div class="bot">bit0=FD bit1=BRS bit2=ESI</div></div>
<div class="cell info"><div class="top">[+6..+7]</div><div class="mid">reserved</div><div class="bot">0x00</div></div>
<div class="cell ok"><div class="top">[+8..+N]</div><div class="mid">data</div><div class="bot">报文数据(dlc 字节)</div></div>
</div>
</div>
<div class="note">
<b>条目大小</b> = 8 + dlc 字节。标准 CAN (dlc=8):14B/条,每页最多 8 条。CANFD (dlc=64):72B/条,每页最多 1 条。<br/>
<b>total_count</b> = 实际不重复 ID 数(0~16,不满 16 就是实际值)。total_count &le; 8 时 page=1 的 entry_count=0。<br/>
<b>ESP32 每轮</b>:每通道发 page=0 和 page=1 两次请求(共 6 次 SPI/s),拉完整张表。
</div>
<div class="section-title">0xC2 request payload 直观图</div>
<div class="diagram">
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">mode</div><div class="bot">0=全收 1=过滤</div></div>
</div>
</div>
<div class="section-title">0xC2 response payload 直观图</div>
<div class="diagram">
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">actual</div><div class="bot">生效模式</div></div>
</div>
</div>
<div class="note">错误码:<code>E0</code>=payload 不足,<code>E1</code>=参数非法(含非法通道),<code>E3</code>=页号非法。</div>
<div class="note">注:<code>E2</code>=快照不可用 仅用于 0xC3,不在 0xC1/0xC2 中返回。</div>
</div>
</details>
</section>
<section class="card">
<h2>ID Snapshot(仅 ID 快照表)</h2>
<div class="sub">注册函数:<code>registerSpiIdSnapshotCommand</code></div>
<details>
<summary>展开查看 ID / payload / 功能</summary>
<div class="inside">
<table>
<tr><th>命令/响应</th><th>符号</th><th>值</th></tr>
<tr><td>命令帧类型</td><td><code>kTypeIdSnapshot</code></td><td><code>0xC3</code></td></tr>
<tr><td>成功响应</td><td><code>kRspAck</code></td><td><code>0x80</code></td></tr>
<tr><td>错误响应</td><td><code>kRspError</code></td><td><code>0x82</code></td></tr>
</table>
<div class="section-title">0xC3 request payload 直观图(分页请求)</div>
<div class="diagram">
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">channel</div><div class="bot">通道 0/1/2</div></div>
<div class="cell ok"><div class="top">[1]</div><div class="mid">page</div><div class="bot">页号 0 或 1</div></div>
</div>
</div>
<div class="section-title">0xC3 response payload 直观图(轻量快照头 + ID 条目)</div>
<div class="sub">应答变长,最大 123 字节。固定头 4B + 条目逐条拼接。</div>
<div class="diagram">
<div class="sub" style="font-weight:600;">固定头(4 字节)</div>
<div class="row">
<div class="cell ok"><div class="top">[0]</div><div class="mid">channel</div><div class="bot">回显通道 0/1/2</div></div>
<div class="cell ok"><div class="top">[1]</div><div class="mid">page</div><div class="bot">回显页号</div></div>
<div class="cell info"><div class="top">[2]</div><div class="mid">total_count</div><div class="bot">ID 条目总数(0~16)</div></div>
<div class="cell info"><div class="top">[3]</div><div class="mid">entry_count</div><div class="bot">本页条目数</div></div>
</div>
<div class="sub" style="font-weight:600;margin-top:14px;">条目区(从 [4] 开始,逐条拼接,变长)</div>
<div class="row">
<div class="cell ok"><div class="top">[+0..+3]</div><div class="mid">id</div><div class="bot">CAN 报文 ID(LE)</div></div>
<div class="cell info"><div class="top">[+4..+7]</div><div class="mid">seq</div><div class="bot">该 ID 更新序号(LE)</div></div>
<div class="cell info"><div class="top">[+8..+11]</div><div class="mid">rx_count</div><div class="bot">该 ID 累计接收(LE)</div></div>
<div class="cell info"><div class="top">[+12]</div><div class="mid">dlc</div><div class="bot">数据长度 1~64</div></div>
<div class="cell info"><div class="top">[+13]</div><div class="mid">flags</div><div class="bot">bit0=FD bit1=BRS bit2=ESI</div></div>
<div class="cell info"><div class="top">[+14..+15]</div><div class="mid">reserved</div><div class="bot">0x00</div></div>
<div class="cell ok"><div class="top">[+16..+N]</div><div class="mid">data</div><div class="bot">报文数据(dlc 字节)</div></div>
</div>
</div>
<div class="note">
<b>条目大小</b> = 16 + dlc 字节。标准 CAN (dlc=8):24B/条,每页最多 5 条。CANFD (dlc=64):80B/条,每页最多 1 条。<br/>
<b>total_count</b> = 实际不重复 ID 数(0~16,不满 16 就是实际值)。total_count &le; 8 时 page=1 的 entry_count=0。<br/>
<b>ESP32 行为</b>:当前代码实现了 0xC3,但主链路主要通过 0xC1 拉取“统计头 + ID 快照表”。
</div>
<div class="note">错误码:<code>E0</code>=payload 不足,<code>E1</code>=通道非法,<code>E2</code>=快照不可用,<code>E3</code>=页号非法。</div>
</div>
</details>
</section>
<section class="card">
<h2>公共响应 / 协议常量</h2>
<div class="sub">来源:<code>app_spi_command_defs.h</code>、<code>app_spi_command.cpp</code></div>
<details>
<summary>展开查看公共 ID / payload</summary>
<div class="inside">
<div class="section-title">公共帧头与响应</div>
<div class="diagram">
<div class="cell info"><div class="top">SOF</div><div class="mid">0xA5</div><div class="bot">起始帧头</div></div>
<div class="cell ok"><div class="top">ACK</div><div class="mid">0x80</div><div class="bot">成功</div></div>
<div class="cell info"><div class="top">WAIT</div><div class="mid">0x81</div><div class="bot">等待中</div></div>
<div class="cell error"><div class="top">ERR</div><div class="mid">0x82</div><div class="bot">错误</div></div>
</div>
<div class="note">公共响应 payload 长度与含义由各命令自行定义。</div>
</div>
</details>
</section>
</div>
<p class="foot">说明:CAN ID 在 CAN Bridge/Feedback 场景下为运行时值,不在文档中固化为常量。</p>
</div>
</body>
</html>