Найдена причина: чип 2 МБ при настройке IDE 4 МБ

Плата имеет физически 2 МБ флеша, в IDE было выбрано 4MB (FS:2MB).
При этой раскладке сектор EEPROM лежит по смещению 0x3FB000, а начало
LittleFS — по 0x400000, тогда как чип заканчивается на 0x200000. Обе
области вне микросхемы, поэтому spi_flash_erase_sector() проваливался
и EEPROM.commit() возвращал false.

Лечится настройкой Flash Size = 2MB (FS:128KB OTA:~960KB), а не кодом:
любая раскладка 2MB кладёт файловую систему ниже 0x1FB000, а EEPROM в
сектор 511. С верной настройкой работали бы оба механизма хранения.

Ранее записанная в README гипотеза про «щель между FS и областью SDK»
была неверной и заменена подтверждённым разбором. Переход на LittleFS
остаётся оправданным по своим качествам, но проблему решает настройка
IDE — в документации это разделено явно, чтобы не ввести в заблуждение
при похожем симптоме на другой плате.

Документация исправлена: плата 2 МБ, а не 4 МБ; требование совпадения
выбранного размера с физическим; предупреждение о потере учётных данных
Wi-Fi при смене раскладки.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-07 19:51:38 +07:00
co-authored by Claude Opus 5
parent 4c0f9672f3
commit 963209dcc9
3 changed files with 75 additions and 25 deletions
+65 -20
View File
@@ -23,7 +23,15 @@
### 2.1 Плата
Wemos D1 Mini (ESP8266, 4 МБ Flash). Питание 5 В по microUSB или 3.3 В на пин `3V3`.
Wemos D1 Mini (ESP8266). Питание 5 В по microUSB или 3.3 В на пин `3V3`.
**Флеш на целевой плате — 2 МБ.** Это важно: клоны Wemos D1 Mini встречаются с
1, 2 и 4 МБ, а размер, выбранный в IDE, обязан совпадать с физическим. Иначе
области EEPROM и файловой системы окажутся за пределами микросхемы и настройки
не сохранятся — см. раздел 6.1, там разобран ровно этот случай.
Проверить фактический размер: `ESP.getFlashChipRealSize()`, прошивка печатает
его в лог при старте строкой `[FLASH] по настройке IDE: ... физически: ...`.
### 2.2 Распиновка
@@ -112,9 +120,23 @@ SSD1306 128×64, I2C, адрес по умолчанию `0x3C` (констан
Board: **LOLIN(WEMOS) D1 R2 & mini**, Upload speed 921600.
**Flash Size обязательно с файловой системой** — например
`4MB (FS:2MB OTA:~1019KB)`. При `FS:none` настройки сохранять некуда; прошивка
сообщит об этом в лог при старте и покажет предупреждение в веб-панели.
**Flash Size: `2MB (FS:128KB OTA:~960KB)`** — под физические 2 МБ целевой платы.
Два требования к этой настройке, оба обязательные:
* **Размер должен совпадать с физическим чипом.** Выбранные 4 МБ на плате с 2 МБ
уводят и EEPROM, и файловую систему за границу микросхемы — настройки молча
не сохраняются (раздел 6.1).
* **Файловая система должна быть ненулевой.** При `FS:none` сохранять настройки
некуда; прошивка скажет об этом в лог при старте и покажет предупреждение в
веб-панели.
Раскладка для 2 МБ (любой из вариантов `2MB (FS:...)`) кладёт файловую систему
ниже `0x1FB000`, а EEPROM — в сектор 511, то есть внутрь чипа.
После смены `Flash Size` заливайте прошивку заново: меняется заголовок
загрузчика и границы областей. Учтите, что **сохранённые учётные данные Wi-Fi
при этом теряются** и прибор поднимет портал `Pump_Control_Set`.
---
@@ -268,26 +290,49 @@ BearSSL ограничен тем же `_timeout`. Чтение ответа о
Строки хранятся как `char[]`, а не `String`: прибор работает месяцами без
перезагрузки, и глобальные `String` фрагментировали бы кучу.
### 6.1 Почему не EEPROM
### 6.1 История: почему настройки не сохранялись
Изначально настройки хранились в эмулируемой EEPROM. На целевой плате это **не
работает**: `EEPROM.commit()` возвращает `false`, то есть падает сам вызов SDK
(`spi_flash_erase_sector` либо `spi_flash_write`), и настройки молча теряются.
Реальный случай, разобранный на этом проекте. Симптом: настройки и webhook
пропадают после перезагрузки.
Проверкой исходников исключены: ошибка в библиотеке EEPROM, перекрытие адресов,
стирание сектора со стороны `WiFiManager::resetSettings()`. Физический размер
флеша тоже ни при чём — LittleFS на том же чипе работает.
**Корневая причина — несовпадение размера флеша.** В IDE было выбрано
`4MB (FS:2MB OTA:~1019KB)`, тогда как физически на плате **2 МБ**:
Наиболее вероятный механизм: при раскладке `4MB (FS:2MB)` сектор EEPROM (1019,
смещение `0x3FB000`) попадает в узкую щель между концом ФС (`0x3FA000`) и
служебной областью SDK (`0x3FC000`) и на этой связке платы и SDK оказывается
защищён от стирания. Доказать это не удалось, поэтому формулировка гипотетическая.
Переход на LittleFS выбран не как обход симптома, а как переезд на механизм,
работоспособность которого на этом железе подтверждена.
| Область | Смещение при настройке 4MB | Внутри чипа 2 МБ (`0x200000`)? |
|---|---|---|
| Сектор EEPROM | `0x3FB000` = 4 173 824 | нет, вдвое дальше конца |
| Начало LittleFS | `0x400000` = 2 097 152 | нет, ровно за границей |
Практическое следствие: **в IDE обязателен вариант `Flash Size` с ненулевой
файловой системой**. При `FS:none` сохранять настройки будет некуда, и прошивка
скажет об этом в лог при старте.
`EEPROM.commit()` возвращал `false`, потому что `spi_flash_erase_sector()`
обращался к несуществующему сектору.
**Лечится настройкой IDE, а не кодом:** любой вариант `2MB (FS:...)` кладёт
файловую систему ниже `0x1FB000`, а EEPROM — в сектор 511, то есть внутрь чипа.
С верной настройкой заработали бы оба механизма хранения.
Что было проверено по пути и оказалось ни при чём: библиотека EEPROM, перекрытие
адресов полей, стирание сектора со стороны `WiFiManager::resetSettings()`
(вызывает только `WiFi.disconnect()`).
**Почему всё-таки перешли на LittleFS**, раз причина была не в EEPROM:
* добавление новой настройки — одна строка, без арифметики адресов и без
версионирования раскладки с миграцией;
* отсутствующий ключ в старом файле не ломает чтение;
* содержимое читается глазами;
* тот же механизм используется в соседних проектах — единообразие.
То есть переход остаётся оправданным по своим качествам, но **проблему решила
настройка `Flash Size`**, а не смена хранилища. Не перепутайте это, если
столкнётесь с похожим симптомом на другой плате.
**Диагностика при старте.** Прошивка печатает геометрию и сама указывает на
несоответствие:
```
[FLASH] по настройке IDE: 4194304 Б, физически: 2097152 Б -> !!! НЕ СОВПАДАЕТ !!!
[FLASH] файловая система: смещение 0x200000, размер 2093056 Б <<< ЗА ПРЕДЕЛАМИ ФИЗИЧЕСКОГО ФЛЕША!
```
### 6.2 Отказоустойчивость