feat(ota): 临时版本,添加zlib压缩支持和SPI通信优化

添加了zlib压缩功能以减少固件传输时间,特别是在弱网环境下
优化了SPI通信参数和错误处理机制

BREAKING CHANGE: 固件版本从0.3.0升级到0.3.1,增加了压缩传输协议

- 在WiFi OTA中集成zlib压缩/解压缩功能
- 添加压缩选项UI界面和前端压缩逻辑
- 修复SPI引脚配置错误(MOSI/MISO接反)
- 优化SPI通信参数设置增加CS时序控制
- 改进OTA重试机制和超时处理
- 扩展ota_relay组件栈大小从8K到12K
- 添加解压缩回调函数和上下文管理
- 更新固件版本号到0.3.1
- 添加更多调试日志和错误检查
This commit is contained in:
小龙虾
2026-05-31 19:09:11 +08:00
parent 1586a81b97
commit c4d78bdfbc
12 changed files with 559 additions and 54 deletions
+55 -6
View File
@@ -836,6 +836,29 @@ function clearFile(chip) {
}
// ==================== 上传固件 ====================
// ==================== zlib compression ====================
async function compressZlib(arrayBuffer) {
var cs = new CompressionStream("deflate");
var writer = cs.writable.getWriter();
writer.write(new Uint8Array(arrayBuffer));
writer.close();
var chunks = [];
var reader = cs.readable.getReader();
for (;;) {
var r = await reader.read();
if (r.done) break;
chunks.push(r.value);
}
var total = chunks.reduce(function(n, c) { return n + c.length; }, 0);
var out = new Uint8Array(total);
var off = 0;
for (var j = 0; j < chunks.length; j++) {
out.set(chunks[j], off);
off += chunks[j].length;
}
return out.buffer;
}
async function startUpload(chip) {
var file = chip === 'esp32' ? esp32File : gd32File;
if (!file || isUploading) return;
@@ -890,19 +913,45 @@ async function startUpload(chip) {
var fileSize = file.size;
var body, url = getBaseUrl() + '/ota/upload';
var useCompress = chip === 'esp32'
? document.getElementById('compressEsp32').checked
: document.getElementById('compressGd32').checked;
if (chip === 'esp32') {
var headerJson = JSON.stringify({ type: 'esp32', total_size: fileSize });
var headerObj = { type: 'esp32', total_size: fileSize };
var payload = arrayBuffer;
if (useCompress) {
payload = await compressZlib(arrayBuffer);
headerObj.compress = 'zlib';
addLog('I', '压缩', 'zlib: ' + formatBytes(fileSize) + ' -> ' + formatBytes(payload.byteLength) + ' (' + Math.round(payload.byteLength * 100 / fileSize) + '%)');
} else {
addLog('I', '上传', '直传(无压缩): ' + formatBytes(fileSize));
}
var headerJson = JSON.stringify(headerObj);
var encoder = new TextEncoder();
var headerBytes = encoder.encode(headerJson);
var fileBytes = new Uint8Array(arrayBuffer);
var combined = new Uint8Array(headerBytes.length + fileSize);
var combined = new Uint8Array(headerBytes.length + payload.byteLength);
combined.set(headerBytes, 0);
combined.set(fileBytes, headerBytes.length);
combined.set(new Uint8Array(payload), headerBytes.length);
body = combined.buffer;
} else {
body = arrayBuffer;
var headerObj = { total_size: fileSize };
var payload = arrayBuffer;
if (useCompress) {
payload = await compressZlib(arrayBuffer);
headerObj.compress = 'zlib';
addLog('I', '压缩', 'zlib: ' + formatBytes(fileSize) + ' -> ' + formatBytes(payload.byteLength) + ' (' + Math.round(payload.byteLength * 100 / fileSize) + '%)');
} else {
addLog('I', '上传', '直传(无压缩): ' + formatBytes(fileSize));
}
var gd32Header = JSON.stringify(headerObj);
var encoder = new TextEncoder();
var headerBytes = encoder.encode(gd32Header);
var combined = new Uint8Array(headerBytes.length + payload.byteLength);
combined.set(headerBytes, 0);
combined.set(new Uint8Array(payload), headerBytes.length);
body = combined.buffer;
}
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
+6
View File
@@ -69,6 +69,9 @@
<div class="file-meta-item"><span>大小</span><b id="fileSizeEsp32">-</b></div>
</div>
</div>
<label style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim);margin-top:8px;cursor:pointer;">
<input type="checkbox" id="compressEsp32"> zlib 压缩(弱网加速,CPU 开销大)
</label>
<button class="btn btn-primary btn-block" id="uploadEsp32Btn" onclick="startUpload('esp32')" disabled style="margin-top:10px;">
上传并升级 ESP32
</button>
@@ -95,6 +98,9 @@
<div class="file-meta-item"><span>大小</span><b id="fileSizeGd32">-</b></div>
</div>
</div>
<label style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim);margin-bottom:4px;cursor:pointer;">
<input type="checkbox" id="compressGd32"> zlib 压缩(弱网加速,CPU 开销大)
</label>
<button class="btn btn-success btn-block" id="uploadGd32Btn" onclick="startUpload('gd32')" disabled style="margin-top:10px;margin-bottom:8px;">
上传固件到缓存
</button>