feat(ecat): 启动后把 ecat_native 提到 RealTime;跳拍优化实验脚本与报告

- esp32_server: Popen 后外部 SetPriorityClass(RT/High),native 自设会被钳成 High
- 入库 skip_* 标定/实验脚本与 REPORT_ecat_skip_opt_20260917
- 前端 WIP:layout/app/polling/boot_ecat/index
- 不含 lab/skip_meter 原始采样与 preview 截图
This commit is contained in:
cbb
2026-09-17 02:32:20 +08:00
parent b3a3a365bb
commit e91d53e0fc
22 changed files with 1956 additions and 61 deletions
+14 -3
View File
@@ -58,6 +58,7 @@ var statusPollInFlight = false; // 是否正在请求 /system/status,防止
var logsInFlight = false; // 是否正在请求 /logs,防止重叠抢 socket
var pageVisible = !document.hidden; // 页面可见性:切到后台/最小化/切标签会变 false
var uploadPollChip = null; // 当前暂停轮询的上传目标,用于区分 WiFi/日志策略
var networkDiagDone = false; // 本轮离线期间是否已做过网关诊断(防每秒刷屏)
/**
* 调整 /system/status 目标间隔。GD32 中继期用 400ms 缩小「转发 N/M」相对设备日志的滞后;
@@ -101,6 +102,7 @@ function scheduleLogsPoll(delayMs) {
export function startPolling() {
window.consecutivePollFailures = 0;
networkDiagDone = false;
statusPollIntervalMs = 1000;
if (statusTimerId) clearTimeout(statusTimerId);
if (logsTimerId) clearTimeout(logsTimerId);
@@ -112,6 +114,7 @@ export function pausePollingForUpload() {
window.pollingPausedForUpload = true;
uploadPollChip = window.activeUploadChip || window.flashTarget || null;
window.consecutivePollFailures = 0;
networkDiagDone = false;
// ★ 上传大固件期间必须停掉 status/logs 轮询。
// httpd max_open_sockets=4 + lru_purge:轮询会再占 socket,LRU 可能踢掉
// 正在写 Flash 的 /ota/upload 连接 → 浏览器 upload 进度已 100%(发完),
@@ -135,6 +138,7 @@ export function resumePollingAfterUpload() {
window.pollingPausedForUpload = false;
uploadPollChip = null;
window.consecutivePollFailures = 0;
networkDiagDone = false;
statusPollIntervalMs = 1000;
if (logsTimerId) clearTimeout(logsTimerId);
// 上传结束立即刷新一次状态;若当前已在请求中,则让它完成后按新间隔继续
@@ -201,6 +205,7 @@ export async function pollStatus() {
// 恢复:之前有失败计数,说明设备曾离线,现在恢复在线
if (window.consecutivePollFailures > 0) {
window.consecutivePollFailures = 0;
networkDiagDone = false;
addLog('I', '系统', '设备已恢复在线,轮询恢复正常');
showToast('设备已恢复在线', 'success');
// 仅清理终态残留。禁止对活跃会话 otaSessionReset:
@@ -278,13 +283,17 @@ export async function pollStatus() {
var otaOngoing = window.pollingPausedForUpload ||
sessionActive || sessionFailed ||
window.isEsp32Rebooting || !!window.currentOtaTarget || lastDeviceBusy;
if (pageVisible && window.consecutivePollFailures >= 5 && !otaOngoing) {
/* EtherCAT 刷写/链路时不跑 WiFi 网关诊断:设备可能根本不在 WiFi 上,
* 反复弹「网关可达;设备不响应」只会干扰。仍走下面的「未连接」UI。 */
var ecatActive = window.connectionMode === 'ecat' || !!window.bootEcatBusy;
if (pageVisible && window.consecutivePollFailures >= 5 && !otaOngoing &&
!ecatActive && !networkDiagDone) {
networkDiagDone = true;
addLog('W', '诊断', '设备连续 5 次无响应,正在诊断网络...');
var diag = await diagnoseNetwork();
addLog('W', '诊断', diag);
addLog('W', '诊断', '诊断结果: ' + diag);
updateConnectionUi(false, '诊断中');
window.applyDisconnectedRuntimeState();
addLog('W', '诊断', '诊断结果: ' + diag);
}
// ★ 状态机优先:会话已 FAILED → 保持失败 UI,仅标连接胶囊为"设备忙/未连接"
if (sessionFailed) {
@@ -353,6 +362,7 @@ document.addEventListener('visibilitychange', function () {
pageVisible = !document.hidden;
if (!pageVisible) return;
window.consecutivePollFailures = 0;
networkDiagDone = false;
// 切回前台立即刷新状态;若当前已在请求中,取消等待中的下一次让它尽快重排
if (statusPollInFlight) {
if (statusTimerId) clearTimeout(statusTimerId);
@@ -419,6 +429,7 @@ setTimeout(function () {
if (ipInput) {
ipInput.addEventListener('change', function () {
window.consecutivePollFailures = 0;
networkDiagDone = false;
addLog('I', '系统', 'IP 已修改,重新启动轮询...');
if (!statusPollInFlight) {
if (statusTimerId) clearTimeout(statusTimerId);