Прошивальщик: данные прошивки передаются строкой в esptool-js (ошибка charCodeAt)

This commit is contained in:
shade committed 2026-10-12 08:53:07 +03:00
1 parent 83f70c2241
commit 9937f26631
3 files changed
+30 -3

No files matched your search

+10
View File
@@ -85,6 +85,16 @@ nginx -t && systemctl reload nginx
- определение чипа при подключении, журнал операций, прогресс, кнопка перезагрузки;
- для nRF52 (`.uf2`, `.zip`) — скачивание и инструкция: копирование на UF2-диск или DFU через nRF Connect.
## Грабли
- **`A.charCodeAt is not a function` при прошивке ESP32.** esptool-js 0.5.x ожидает содержимое
файла как «двоичную строку»: внутри `writeFlash` вызывается `bstrToUi8(data)`, то есть
`data.charCodeAt(i)`. Если передать `Uint8Array`, запись падает. В `app.js` байты приводит
`bytesToBinaryString()` (кусками по 32 КБ, чтобы не упереться в лимит аргументов).
- **Браузер держит старый `app.js`.** Для `location /flasher/` в nginx стоит
`Cache-Control: no-cache`, а подключение в `index.html` идёт с версией (`app.js?v=...`).
При правке скрипта версию нужно поднять, иначе браузер возьмёт старый файл из кэша.
## Ограничения
- прошивка из браузера возможна только для ESP32: nRF52 требует UF2-диска или DFU;
+19 -2
View File
@@ -213,13 +213,30 @@ async function connect() {
}
}
// esptool-js (0.5.x) ожидает содержимое прошивки как «двоичную строку» (binary string):
// внутри writeFlash вызывается bstrToUi8(data), то есть data.charCodeAt(i). Если передать
// Uint8Array, падает с "data.charCodeAt is not a function" — поэтому конвертируем сами.
function bytesToBinaryString(bytes) {
let out = '';
const CHUNK = 0x8000; // чтобы String.fromCharCode.apply не упёрся в лимит аргументов
for (let i = 0; i < bytes.length; i += CHUNK) {
out += String.fromCharCode.apply(null, bytes.subarray(i, i + CHUNK));
}
return out;
}
async function fetchFirmware(file) {
log('Загрузка ' + file.name + ' (' + human(file.size) + ')…');
const res = await fetch(file.url, { cache: 'no-store' });
if (!res.ok) throw new Error('не удалось скачать файл: HTTP ' + res.status);
const buf = await res.arrayBuffer();
log('Получено ' + human(buf.byteLength));
return new Uint8Array(buf);
const bytes = new Uint8Array(buf);
log('Получено ' + human(bytes.length) + ', подготовка данных…');
const data = bytesToBinaryString(bytes);
if (data.length !== bytes.length) {
throw new Error(`данные повреждены при подготовке: ${data.length} вместо ${bytes.length} байт`);
}
return data;
}
async function flash() {
+1 -1
View File
@@ -112,6 +112,6 @@
</footer>
</div>
<script type="module" src="app.js"></script>
<script type="module" src="app.js?v=20261012"></script>
</body>
</html>