feat(motor-ota): 改进电机OTA中继的握手确认和重试机制
- 添加握手确认逻辑,避免在握手阶段就标记TRANSFER状态 - 实现GD32 auto-retry检测机制,当连续WAIT超限时查询真实状态 - 修复预填充缓冲区数据重复问题,移除旧的offset重置逻辑 - 优化SPI响应等待机制,允许在WAIT后重发DATA以恢复丢失的ACK - 添加连续SPI失败和WAIT计数监控,超过阈值时主动查询GD32状态 perf(can): 提升CAN批量发送性能和可靠性 - 将CAN帧间延迟从5ms减少到1ms以提升传输速度 - 将单批最大帧数从32增加到64,并将批次间隔从200ms减少到100ms - 添加手动超时控制器防止fetch请求永久挂起 - 实现批量发送完成后的兜底渲染机制确保结果正确显示 refactor(spi): 优化SPI通信的事件驱动机制 - 实现基于信号量的事件驱动等待机制,替换原有的轮询方式 - 将SPI时钟频率从4MHz提升至8MHz以提高传输速度 - 优化OTA发送后的静默期处理,不同类型的命令采用不同的延迟策略 - 添加临时SPI测速端点用于性能测试 chore(version): 更新固件版本至0.3.74 - 版本号从0.3.72提升到0.3.74 - 更新前端资源版本号以确保缓存刷新
This commit is contained in:
+26
-12
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
import { state, el, getBaseUrl, padHex, bytesToHex, parseNumericId } from './dbc.js';
|
||||
import { escapeHtml } from '../common/utils.js';
|
||||
import { showToast } from '../common/toast.js';
|
||||
import { showToast } from '../common/toast.js?v=20260801f';
|
||||
import { updateBatchUi } from './messages.js';
|
||||
import { ensureMessageDefaults, getSignalValueMap, getSelectedMessage, updateEncodedPreview, encodeMessageData } from './signals.js';
|
||||
import { scheduleCanPersist } from './persist.js';
|
||||
@@ -124,12 +124,23 @@ async function sendCanBatchRequest(channel, frames) {
|
||||
var n = frames && frames.length ? frames.length : 0;
|
||||
/* 单帧设备侧 timeout 2s;多帧按帧数留余量 */
|
||||
var timeoutMs = (n <= 1) ? 8000 : Math.max(15000, n * 500);
|
||||
var resp = await fetch(getBaseUrl() + '/can/send_batch', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ ch: channel, frames: frames }),
|
||||
signal: AbortSignal.timeout(timeoutMs)
|
||||
});
|
||||
/* AbortSignal.timeout 在连接被 reset 的边缘情况下偶发不触发,
|
||||
* 叠加一条手动竞速超时,避免 await 永久挂起导致整批不渲染。 */
|
||||
var ac = new AbortController();
|
||||
var timer = setTimeout(function () { ac.abort(); }, timeoutMs);
|
||||
var resp;
|
||||
try {
|
||||
resp = await fetch(getBaseUrl() + '/can/send_batch', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ ch: channel, frames: frames }),
|
||||
signal: ac.signal
|
||||
});
|
||||
} catch (err) {
|
||||
throw new Error('请求失败: ' + (err && err.message ? err.message : err));
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
var text = await resp.text();
|
||||
var json = {};
|
||||
try {
|
||||
@@ -231,12 +242,12 @@ export function renderHistory() {
|
||||
|
||||
// ==================== 批量发送 ====================
|
||||
/**
|
||||
* 单批最多帧数。实测一次发送 >9 帧失败率明显上升,故按 9 帧分批;
|
||||
* 批次之间留 BATCH_INTER_CHUNK_DELAY_MS 间隔,给 CAN/SPI 总线喘息时间。
|
||||
* 单批最多帧数。按 64 帧分批(一次请求发 64 帧);批次之间留
|
||||
* BATCH_INTER_CHUNK_DELAY_MS 间隔,给 CAN/SPI 总线喘息时间。
|
||||
*/
|
||||
var BATCH_CHUNK = 32;
|
||||
var BATCH_CHUNK = 64;
|
||||
/** 批次间延时(ms),仅在还有后续批次时等待 */
|
||||
var BATCH_INTER_CHUNK_DELAY_MS = 200;
|
||||
var BATCH_INTER_CHUNK_DELAY_MS = 100;
|
||||
|
||||
/**
|
||||
* @description 批量发送所有勾选的报文(仅 /can/send_batch)。
|
||||
@@ -330,10 +341,13 @@ export async function sendCheckedMessages() {
|
||||
renderHistory();
|
||||
scheduleCanPersist();
|
||||
var tone = fail === 0 ? 'success' : (ok === 0 ? 'error' : 'warning');
|
||||
showToast('批量发送完成:成功 ' + ok + ',失败 ' + fail, tone);
|
||||
showToast('批量发送完成:成功 ' + ok + ',失败 ' + fail, tone, { force: true });
|
||||
} finally {
|
||||
state.batchInFlight = false;
|
||||
updateBatchUi();
|
||||
/* 兜底渲染:无论 try 内是否抛异常,都保证已写入的 silent 历史条目可见,
|
||||
* 避免「批量发了但结果不显示」的偶发现象(renderHistory 幂等,多调一次无害)。 */
|
||||
renderHistory();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user