docs(lab): 更正 PRAM 写归因为从站侧成本;lan9252_pm 加 pmHold 看门狗豁免
This commit is contained in:
@@ -1 +1 @@
|
||||
dda92d11876f059d27390232e88b5c9fa7c0eb57e442365f5247d4acdefb9b20
|
||||
c6827f84e9b8fa07288d0fc2081d0efc48a6ef2c5b8124b85a406f3a7a02042a
|
||||
+30
-1
@@ -260,19 +260,31 @@
|
||||
}
|
||||
|
||||
/* 跨标签/重载保持睡眠:HBI 读会唤醒芯片,页面销毁后现场丢失会导致
|
||||
* 切回时自动 poll(1E) 把睡眠叫醒。用 sessionStorage 记档位,重载时跳过自动读。 */
|
||||
* 切回时自动 poll(1E) 把睡眠叫醒。sessionStorage 记本标签档位;另存一份
|
||||
* localStorage 供换标签页/重开浏览器时兜底(宁可按睡眠处理少一次自动读,
|
||||
* 也不能自动 1E 把芯片叫醒)。 */
|
||||
var SS_SLEEP = "lan9252_pm_asleep";
|
||||
var LS_SLEEP = "lan9252_pm_asleep_any";
|
||||
function saveSleepFlag(n) {
|
||||
try { sessionStorage.setItem(SS_SLEEP, String(n)); } catch (e) {}
|
||||
/* localStorage: "n@ms" —— 带时间戳,换标签/重开浏览器可追溯入睡时刻 */
|
||||
try { localStorage.setItem(LS_SLEEP, n + "@" + Date.now()); } catch (e) {}
|
||||
}
|
||||
function clearSleepFlag() {
|
||||
try { sessionStorage.removeItem(SS_SLEEP); } catch (e) {}
|
||||
try { localStorage.removeItem(LS_SLEEP); } catch (e) {}
|
||||
}
|
||||
function loadSleepFlag() {
|
||||
try {
|
||||
var v = sessionStorage.getItem(SS_SLEEP);
|
||||
if (v === "1" || v === "2" || v === "3") return parseInt(v, 10);
|
||||
} catch (e) {}
|
||||
try {
|
||||
var lv = localStorage.getItem(LS_SLEEP) || "";
|
||||
/* 兼容旧值 "1"/"2"/"3" 与新值 "1@1760029000000" */
|
||||
var m = String(lv).match(/^([123])(?:@(\d+))?$/);
|
||||
if (m) return parseInt(m[1], 10);
|
||||
} catch (e) {}
|
||||
return 0;
|
||||
}
|
||||
function renderAssumedSleep(n) {
|
||||
@@ -299,6 +311,7 @@
|
||||
/* 仅在确认芯片已离开睡眠(唤醒成功 / 读到 SLEEP_EN=0 / NRST)时清 flag */
|
||||
function markAwake() {
|
||||
clearSleepFlag();
|
||||
pmHold(0); /* 芯片已醒:解除主站看门狗豁免,恢复正常自愈 */
|
||||
$("sleepBanner").textContent =
|
||||
"🌙 芯片处于低功耗档 —— EtherCAT 通信已中断,点「手动唤醒」恢复";
|
||||
}
|
||||
@@ -396,6 +409,17 @@
|
||||
function ecatMotorStart(timeoutMs) {
|
||||
return ecatPost("motor/start", {}, timeoutMs || 30000);
|
||||
}
|
||||
/* 主站楔死看门狗豁免:休眠期间 ecat_native 不判死不重拉(否则芯片醒来
|
||||
* 即被偷偷拉回 OP——2026-09-12 实测休眠 ~20s 自动"复活")。解除时主站
|
||||
* 自带 60s 冷却,让本页唤醒流程先走完。best-effort:native 未起只记日志。 */
|
||||
function pmHold(on) {
|
||||
return ecatPost("pm/hold", { on: on }, 5000).then(function (r) {
|
||||
log("主站看门狗豁免" + (on ? "置位" : "解除") +
|
||||
(r.ok ? "" : "失败: " + r.log.join(";")), r.ok ? "ok" : "warn");
|
||||
}).catch(function (e) {
|
||||
log("主站看门狗豁免" + (on ? "置位" : "解除") + "失败: " + e.message, "warn");
|
||||
});
|
||||
}
|
||||
function ecatEnsureOpen() {
|
||||
/* bus_open=0 时 motor/start 直接回「未连接」。与电机页 ensureOpen 同源。 */
|
||||
return ecatPost("native/health", {}, 6000).then(function (h) {
|
||||
@@ -420,6 +444,7 @@
|
||||
});
|
||||
}
|
||||
function recoverEcatMaster() {
|
||||
pmHold(0); /* 唤醒流程开始即解除豁免(主站给 60s 冷却,不干扰本流程) */
|
||||
log("重连 EtherCAT 主站:stop → open → NRST → motor/start …", "warn");
|
||||
/* 先停在跑的 PDO 循环,避免与 NRST/init 抢总线 */
|
||||
return ecatPost("motor/stop", {}, 8000).catch(function () { return { ok: true, log: ["stop 跳过"] }; })
|
||||
@@ -519,6 +544,7 @@
|
||||
pollPaused = true;
|
||||
setConn(true, "睡眠中 · 轮询已暂停");
|
||||
saveSleepFlag(n);
|
||||
pmHold(1); /* 请主站看门狗整段静默,别把睡着/刚醒的芯片偷偷拉回 OP */
|
||||
renderStatus(b);
|
||||
/* 固件返回可能是新 status 或旧字节;强制按 D{n} 展示并记住 */
|
||||
setCell("stSleep", "1", "v-warn");
|
||||
@@ -568,6 +594,9 @@
|
||||
renderAssumedSleep(restoredSleep);
|
||||
setConn(true, "上次睡眠中 · 轮询已暂停");
|
||||
log("恢复上次会话:D" + restoredSleep + " 睡眠中。为避免 HBI 读唤醒芯片,已跳过自动状态刷新;点「读状态」或「手动唤醒」继续。", "warn");
|
||||
/* 新标签/重开浏览器:native 可能刚重启导致 g_pm_hold=0,楔死线程会趁
|
||||
* 芯片睡着时重拉(D1/D2 报文即唤醒)。必须重新置位豁免。 */
|
||||
pmHold(1);
|
||||
probeEspOnly();
|
||||
} else {
|
||||
log("就绪。状态每 2s 自动刷新;改设备 IP 请到 OTA 中继页(全局共享)。", "warn");
|
||||
|
||||
+7
-7
@@ -252,7 +252,7 @@ footer code{font-size:11px}
|
||||
<div class="pills">
|
||||
<span class="pill">真源 <b>ethercat_can_bridge.h</b></span>
|
||||
<span class="pill">尺寸 <b>ethercat_pdo_size.h</b></span>
|
||||
<span class="pill">PRAM <b>0.441 µs/B</b></span>
|
||||
<span class="pill">PRAM 写 <b>从站侧</b>(≠ 主站 rx)</span>
|
||||
<span class="pill">魔数 <b>@35=0xA5</b></span>
|
||||
<span class="pill">电机槽 <b>≤9 × 56 B</b></span>
|
||||
<span class="pill">稀疏写 <b>CONFIG=1</b></span>
|
||||
@@ -437,20 +437,20 @@ for (i = 0; i < count; i++) {
|
||||
<div class="sec-head">
|
||||
<span class="sec-no">4</span>
|
||||
<h2>每拍成本与 SM 预算</h2>
|
||||
<span class="tagline">PRAM ≈0.441 µs/B · 稀疏写 1.6.22+</span>
|
||||
<span class="tagline">从站写 ESC 成本 · 稀疏写 1.6.22+(不是主站 rx)</span>
|
||||
</div>
|
||||
|
||||
<div class="cost-grid">
|
||||
<div class="cost-card c-cyan">
|
||||
<div class="lbl">输入写侧 · 3 电机稀疏</div>
|
||||
<div class="val">116</div>
|
||||
<div class="unit">µs/拍 · 264 B×0.441 · 11.6% @1ms</div>
|
||||
<div class="val">—</div>
|
||||
<div class="unit">从站写 ESC · 按实占字节估(≠ 主站 rx)</div>
|
||||
<div class="bar"><i style="width:11.6%"></i></div>
|
||||
</div>
|
||||
<div class="cost-card c-blue">
|
||||
<div class="lbl">输入写侧 · 整包基线</div>
|
||||
<div class="val">265</div>
|
||||
<div class="unit">µs/拍 · 600×0.441 · 26.5% @1ms</div>
|
||||
<div class="val">—</div>
|
||||
<div class="unit">从站写 ESC · 600B 整包(≠ 主站 rx)</div>
|
||||
<div class="bar"><i style="width:26.5%"></i></div>
|
||||
</div>
|
||||
<div class="cost-card c-amber">
|
||||
@@ -524,7 +524,7 @@ count=9 → 整包 600 B(两段相接,回退)</code></pre>
|
||||
布局真源 <code>comm/ethercat_can_bridge.h</code>(1.6.21)· 尺寸 <code>comm/ethercat_pdo_size.h</code> ·
|
||||
固件版本 <code>config.h APP_FW_VERSION = 1.6.24</code> ·
|
||||
稀疏写 <code>ethercat_pdo.cpp sparseEscWritePlan</code> + <code>ecatappl.c PDO_InputMapping</code> ·
|
||||
成本系数 <code>0.441 µs/B</code> · 布局魔数 <code>kEcatMotLayoutMagic = 0xA5</code>
|
||||
成本说明:从站写 ESC 与主站 rx 是两段时间 · 布局魔数 <code>kEcatMotLayoutMagic = 0xA5</code>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
+1842
-1869
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user