From 963209dcc9e91d5baa3ca7a320bb1d0aaa3d535f Mon Sep 17 00:00:00 2001 From: Vitali Date: Fri, 7 Aug 2026 19:51:38 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D0=B9=D0=B4=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD=D0=B0:=20=D1=87=D0=B8?= =?UTF-8?q?=D0=BF=202=20=D0=9C=D0=91=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B5=20IDE=204=20=D0=9C?= =?UTF-8?q?=D0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Плата имеет физически 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 --- pump_controller_8_2_OLED_DONE/MANUAL.md | 8 +- pump_controller_8_2_OLED_DONE/README.md | 85 ++++++++++++++----- .../pump_controller_8_2_OLED_DONE.ino | 7 +- 3 files changed, 75 insertions(+), 25 deletions(-) diff --git a/pump_controller_8_2_OLED_DONE/MANUAL.md b/pump_controller_8_2_OLED_DONE/MANUAL.md index ca07538..4b45c05 100644 --- a/pump_controller_8_2_OLED_DONE/MANUAL.md +++ b/pump_controller_8_2_OLED_DONE/MANUAL.md @@ -172,9 +172,11 @@ STATUS: OK Настройки сохраняются в файл во внутренней памяти прибора, переживают отключение питания и сброс Wi-Fi. -> Если панель показывает красное предупреждение «Файловая система недоступна», -> настройки работают только до перезагрузки. Причина почти всегда в настройке -> `Flash Size` при прошивке — нужен вариант с файловой системой, не `FS:none`. +> Если панель показывает красное предупреждение «Файловая система недоступна» +> или настройки пропадают после перезагрузки — причина в настройке `Flash Size` +> при прошивке. Она обязана совпадать с фактическим размером памяти платы: +> для этих приборов **`2MB (FS:128KB OTA:~960KB)`**. Вариант `4MB` на плате с +> 2 МБ приводит ровно к такому симптому. > Русские буквы и пробелы в имени устройства **не сохранятся** — они будут > отброшены. Это не ошибка: ограничение защищает формат уведомления от поломки. diff --git a/pump_controller_8_2_OLED_DONE/README.md b/pump_controller_8_2_OLED_DONE/README.md index 8fa026a..f82b037 100644 --- a/pump_controller_8_2_OLED_DONE/README.md +++ b/pump_controller_8_2_OLED_DONE/README.md @@ -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 Отказоустойчивость diff --git a/pump_controller_8_2_OLED_DONE/pump_controller_8_2_OLED_DONE.ino b/pump_controller_8_2_OLED_DONE/pump_controller_8_2_OLED_DONE.ino index 8b7a68a..7660449 100644 --- a/pump_controller_8_2_OLED_DONE/pump_controller_8_2_OLED_DONE.ino +++ b/pump_controller_8_2_OLED_DONE/pump_controller_8_2_OLED_DONE.ino @@ -36,8 +36,11 @@ - ESP8266WiFi / ESP8266WebServer / ESP8266HTTPClient / LittleFS (часть ESP8266 core) - В IDE обязателен вариант Flash Size с ненулевой файловой системой, - например «4MB (FS:2MB OTA:~1019KB)» — иначе настройки сохранять некуда. + ВАЖНО про Flash Size в IDE. Целевая плата имеет 2 МБ флеша, ставить нужно + «2MB (FS:128KB OTA:~960KB)». Выбранный размер обязан совпадать с физическим: + при настройке 4MB на чипе 2MB области EEPROM и файловой системы уходят за + границу микросхемы, и настройки молча не сохраняются. Прошивка печатает + фактический размер в лог при старте строкой [FLASH]. ============================================================ */