- 添加CAN反馈和ID快照SPI命令文件 - 移除EXMC组件依赖,精简项目配置 - 添加RAM函数段链接脚本,优化Flash等待周期抖动 - 实现EscExmcBus类,提供16位并行总线访问LAN9252 - 实现EscLan9252驱动,支持寄存器和PDI内存访问 - 实现EthercatSlave类,采用三缓冲机制进行PDO数据交换 - 实现EthercatSync同步管理,支持SYNC0/SYNC1中断和定时器模式 - 添加ISR执行时间统计和诊断功能 - 分离周期路径和事件路径通知机制,避免RMW竞态
339 lines
20 KiB
HTML
339 lines
20 KiB
HTML
<!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 ≤ 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 ≤ 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>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|