Добрый день, уважаемые читатели!
Как вы, наверное, уже знаете – у SoC и модулей ESP нет микросхемы EEPROM. Все данные – и двоичные данные прошивки, и файлы (если есть), и все переменные хранятся исключительно на flash-памяти. При этом весь доступный объем микросхемы flash-памяти разбивается на несколько отдельных разделов, в каждом из которых хранится та или информация. Например, для хранения различных параметров и настроек ESP32 разработчики предусмотрели супер-удобнейший раздел NVS, но об нем конкретно мы поподробнее поговорим в следующей статье.
В этой статье поговорим о том, как распределяется общее доступное пространство flash-памяти между собственно прошивкой и вашими прикладными данными. Статья будет вам полезна, если вы хотите разобраться что такое таблица разделов, где она расположена, и почему места под прошивку зачастую сильно меньше 4MB. Из нее вы также сможете узнать, как создать свою собственную таблицу разделов под свою конкретную задачу, вне зависимости от того, в какой среде разработки вы работаете и какой фреймворк предпочитаете.
Оглавление
- Таблица разделов ESP
- Перепрошивка таблицы разделов
- Стандартные таблицы разделов
- Создаем свою таблицу разделов
- Проверка созданной таблицы разделов
- Подключение таблицы разделов к проекту ESP-IDF
- GUI редактор таблицы разделов ESP IDE
- Ссылки
Таблица разделов ESP
Flash-память каждой ESP может хранить загрузчик, одно или несколько приложений, а также множество различных дополнительных данных: данные калибровки, различные параметры, файловые системы и т. д. Это очень похоже на таблицу разделов обычного компьютера – на обычном ПК вы также можете создать несколько разделов (например диск С:\ и диск D:\) на одном и том же физическом жестком диске.
Для того, чтобы задать необходимую структуру расположения разнородных данных на flash, используется таблица разделов. Именно таблица разделов определяет, что где лежит и когда все это кончится. Таблица разделов записывается на ту же самую flash-память по адресу 0x8000 в flash-памяти (то есть сразу после загрузчика). Она занимает 4 КБ, поэтому первый раздел после неё должен начинаться не раньше адреса 0x9000 [Partition Tables].
Важные ограничения таблицы разделов ESP32:
- Каждый сектор flash памяти имеет минимальный размер 4 КБ или 0x1000 байт в шестнадцатеричном представлении (здесь и далее все размеры – именно в шестнадцатеричном виде). Все размеры и смещения должны быть выровнены по этому значению –
0x1000,0x2000и т.д. То есть задать размер раздела0x0100или0x0500у вас не выйдет. - Начальная область Flash-памяти по умолчанию занята под загрузчик. Поэтому прикладные разделы должны располагаться начиная с адреса, заданного в константе CONFIG_PARTITION_TABLE_OFFSET – это так называемое смещение по умолчанию (плюс размер самой таблицы – об этом далее). На момент написания статьи это значение равно 0x8000. Однако, в некоторых случаях загрузчик не впихивается в отведенное ему место (например если вы включили отладочные сообщения в лог для загрузчика) и в этом случае вам потребуется увеличить это значение и сдвинуть все последующие разделы.
- Длина таблицы разделов составляет 0xC00 байт, то есть допускается максимум 95 записей. Контрольная сумма MD5, используемая для проверки целостности таблицы разделов во время запуска, добавляется сразу же после данных таблицы. Таким образом, таблица разделов занимает ровно один сектор флэш-памяти. В результате любой следующий за ним раздел должен располагаться как минимум по адресу смещение по умолчанию + 0x1000. То есть начало “пользовательской” таблицы разделов сдвигается до 0x9000.
Как выглядит файл таблицы разделов
Для начала давайте познакомимся с самим файлом таблицы разделов. Это обычный текстовый файл в формате CSV (значения через запятую, в кодировке UTF-8 без BOM, но это не имеет особого значения, так как в нём допускаются только кошерные символы латиницы, а они в любой кодировке занимают ровно 1 байт).
- Каждая строка определяет один раздел (исключая комментарии, которые начинаются с символа
#) - Для каждого раздела должны быть указаны следующие поля:
Name,Type,SubType,Offset,SizeиFlags - Загрузчик указывать не нужно
Например:
# ESP-IDF Partition Table # 4MB FLASH (0x400000): 2 OTA + 2 NVS (sys+app) + 2 cert bundle + coredump # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, certs_factory, data, 0x40, 0x20000, 0x18000, certs_app, data, 0x41, 0x38000, 0x18000, ota_0, app, ota_0, 0x50000, 0x1d0000, ota_1, app, ota_1, 0x220000, 0x1d0000, coredump, data, coredump, 0x3f0000, 0x10000,
Каждая строка в таблице разделов имеет имя (метку), тип (приложение, данные или что-то еще), подтип, смещение во флэш-памяти, куда будет загружен этот раздел, и его размер. Опционально можно дополнительные флаги (опции).
Name
Имя раздела — оно может содержать до 16 символов. По этому имени загрузчик или ваша программа может обращаться к нему.
Есть стандартные имена разделов, известные системе сборки заранее: nvs, coredump, которые системные API “знают” заранее. Например wifi драйвер будет искать настройки в системном NVS-разделе, который так и назван – nvs. К загрузочным разделам загрузчик обращается не по имени, а по субтипу. Например загрузчик “знает”, что основное приложение лежит в разделе с типом app и субтипом factory, а название раздела ему, в общем-то, “до лампочки”.
Но для “своих собственных” котов разделов вы можете задать произвольные имена, главное чтобы они были одинаковы.
Type и SubType
Тип и подтип раздела — самая важная часть таблицы разметки. Эти поля определяют, какого мусора тут накидано типа данные хранятся в данном разделе.
Типов всего два – app и data, подтипов у них гораздо больше:
🔹 app, он же ESP_PARTITION_TYPE_APP (цифровое значение 0x00)
Разделы этого типа предназначены для хранения прошивки (application – приложение), таких разделов может быть как минимум один или больше.
Важно! Для разделов типа app его размер и посадочное место (смещение) должны быть выровнены до 0x10000 (64 КБ)!
Ну и, конечно же, размер раздела должен быть не меньше размера скомпилировано вами кода с запасом на будущие модификации. Но не слишком увлекайтесь – иначе на другие разделы места не останется. 30%~50% к размеру текущей прошивки “на вырост” будет оптимальным выбором. Если таких разделов несколько (например два раздела OTA – желательно, чтобы их размеры совпадали, хотя это не строго обязательно.
factory (0x00)
Раздел, предназначенный для “заводского” приложения, то есть в состоянии до применения любых OTA-обновлений.
Не обязательный раздел, если вы используете OTA и наоборот – обязательный, если разделов OTA нет. Если он есть, то он должен быть в единственном числе.
Сюда по умолчанию система сборки ESP-IDF помещает скомпилированный код во время прошивки ESP32 кабелем. Загрузчик запустит это “заводское” приложение, если не обнаружит разделы типа ota, например если процедура OTA завершилась с ошибкой. Если этот раздел отсутствует, прошивка будет записана в свободный OTA-раздел.
ОТА никогда не перезаписывает этот раздел, поэтому вы можете быть уверены, что ваше устройство гарантировано запустится, даже если вы путем сложной комбинации кривых рук ушатали все свои ota-разделы.
ota_0 (0x10) … ota_15 (0x1F)
Слоты для OTA-прошивок. Сюда будет помещен код прошивки, полученный “на лету” через WiFi и OTA. Сюда же упадет код при прошивке “с кабеля” в случае, если раздел factory отсутствует.
Если вы планируете использовать OTA – то вам нужно как минимум два таких раздела, и у каждого из них должен быть уникальный субтип.
Как работает этот механизм, я упоминал в другой статье.
test (0x20)
Зарезервированный подтип для тестовых прошивок. Но он также может использоваться в качестве резервного загрузочного раздела, если не будет найден другой допустимый раздел приложения (factory или ota).
Можно настроить загрузчик на чтение специального Strapping pin во время каждой загрузки и загрузку этого раздела, если соответствующее GPIO удерживается на низком уровне, см. загрузка тестовой прошивки.
🔹 data, он же ESP_PARTITION_TYPE_DATA (цифровое значение 0x01)
К этому типу относятся любые разделы, в которых хранятся какие-либо данные, не важно какие.
ota (0x00)
Специальный раздел служебных данных для системы OTA , в котором хранится информация о выбранном в данный момент слоте приложения OTA.
Этот раздел обязателен только при наличии двух или более OTA разделов типа app и должен иметь размер ровно 0x2000 байт. Если вы не используете OTA разделы – этот раздел также не нужен!
Дополнительные сведения смотрите в документации OTA.
phy (0x01)
Данный раздел предназначен для хранения параметров инициализации радиомодема WiFi и BT уровня PHY. Это позволяет настраивать радиооборудование для каждого устройства без внесения изменений в прошивку.
В конфигурации по умолчанию раздел phy не используется вовсе, вместо этого данные инициализации оборудования компилируются в само приложение. Таким образом, в большинстве приложений этот раздел можно удалить из таблицы разделов для экономии места. Особенно если вы не выпускаете свои устройства крупными партиями для разных стран.
nvs (0x02)
Этот раздел предназначен для хранения различных настроек и параметров в формате “ключ” – “значение”, используя API энергонезависимого хранилища данных (NVS). NVS API можно (и нужно!) использовать для записи настроек вашего приложения.
Рекомендуемый размер NVS раздела для пользовательских конфигов – 32 ~ 64 килобайта, но не менее 12 КБ. Больше 64 КБ можно, но не нужно, так как сильно растет расход оперативной памяти RAM (~0.5 КБ для 24КБ, ~1.4 КБ для 64КБ, ~2.8 КБ для 128КБ, ~11 КБ для 512КБ) для хранения индекса ключей – поэтому сильно не увлекайтесь. Но и слишком небольшой размер – тоже не есть карашо.
NVS раздел, в том числе, используется и самой ESP-IDF для хранения данных калибровки радиооборудования для каждого конкретного экземпляра устройства (отличных от данных инициализации PHY) и для хранения параметров WiFi-драйвера, если используется функция инициализации esp_wifi_set_storage (WIFI_STORAGE_FLASH). Для этих целей справочная система рекомендует зарезервировать не менее 24 КБ в NVS-разделе. Поэтому рекомендуется использовать отдельные разделы NVS для системных данных (WiFi и т.д.) и данных вашего приложения, дабы уменьшить накладные расходы RAM (так как расход памяти увеличивается с размером NVS не линейно).
nvs_keys (0x04)
Служебный раздел NVS, который используется для хранения ключей шифрования NVS, но только когда включена функция шифрования NVS. Если шифрование данных не используется, то и этот раздел не нужен.
Размер этого раздела должен быть ровно 0x1000 байт.
coredump (0x03)
Специальный раздел, куда можно поместить дамп памяти и регистры процессора при сбое и перезагрузке процессора из-за паники. После перезагрузки можно считать данные из этого раздела и попытаться расшифровать их, чтобы выяснить причину сбоя на удаленном устройстве.
Core dump — это снимок состояния программного обеспечения, который автоматически сохраняется обработчиком паники (panic handler) при возникновении фатальной ошибки. Core dump позволяет проводить посмертный анализ (post-mortem analysis) состояния системы в момент сбоя. Конкретно он содержит:
- Снимки всех задач (tasks) в момент паники — каждый снимок включает TCB (Task Control Block) и стек задачи
-
Регистры CPU упавшей задачи
-
Содержимое стеков всех задач
-
Сводку причины паники
Анализируя эти данные, можно выяснить:
-
Какая задача вызвала панику
-
На какой инструкции (строке кода) произошёл сбой
-
Какой был стек вызовов (call stack)
-
Значения переменных (если они размещены на стеке, а не в куче или css)
0x40–0xFE
Дополнительно вы можете использовать кастомные подтипы для хранения каких-либо специальных данных, например пакета корневых сертификатов TLS. В этом случае можно быстро заменить пакет сертификатов, “не трогая” основную прошивку.
Файловые системы
fat (ESP_PARTITION_SUBTYPE_DATA_FAT)
Позволяет организовать на flash-памяти файловую систему FAT. FAT лучше подходит, когда:
-
Нужна совместимость с ПК (SD-карты, USB-накопители)
-
Требуется структура директорий
-
Хранятся аудио/видео файлы или большие файлы
-
Нужно шифрование данных
-
Используются SD-карты
spiffs (ESP_PARTITION_SUBTYPE_DATA_SPIFFS)
Позволяет организовать файловую систему SPIFFS. SPIFFS лучше подходит, когда:
-
Нужна минимальная RAM (низкое потребление ресурсов)
-
Хранится много мелких файлов без необходимости в директориях
-
Важен статический wear levelling без дополнительной настройки
-
Используется только SPI NOR Flash
Offset
Смещение раздела относительно начала таблицы (включая загрузчик и саму таблицу). То есть это начало раздела на “диске” или его физический адрес. Задается в байтах в HEX-формате.
Обязательно учитывайте, что:
- смещение первого раздела вашей таблицы должно начинаться как минимум с
0x9000. - каждый новый раздел не должен накладываться на предыдущий
- начало каждого раздел должно быть выровнено до 4KB для данных или до 64KB для приложений (смещение типа 0x13001 не допускается).
Size
Размер раздела. Также как и смещение, должен быть выровнен до 4KB для данных или до 64KB для приложений. Здесь можно указать не только байты в HEX-формате, но и килобайты (64K) и мегабайты (1M).
Flags
Дополнительные флаги, которые определяют специальные особенности раздела – например наличие шифрования. Но очень часто это поле просто остается пустым. Более подробно смотрите в документации.
Перепрошивка таблицы разделов
Простое обновление таблицы разделов через upload не стирает данные, которые были записаны согласно старой таблицы. Поэтому, чтобы избежать наложения старых данных на новые разделы, при изменении таблицы разделов необходимо полностью очистить микросхему памяти.
Если в процессе работы над проектов в какой-то момент вам необходимо изменить уже существующую таблицу разделов, то перед тем, как записать новую таблицы – вы должны будете предварительно очистить / стереть всю микросхему FLASH-памяти. Разумеется, все сохраненные данные (например в NVS разделах и в файловых системах) при этом будут утеряны.
Этот процесс занимает довольно много времени и может привести к преждевременному износу памяти – поэтому не стоит выполнять эту процедуру слишком часто на “рабочем” устройстве. Если вы хотите больше узнать, как устроена и работает flash-память – рекомендую почитать статью на Хабре.
Отсюда вывод: для сложной проектной работы и отладки желательно иметь тестовую копию устройства. Дабы иметь возможность “залить” в рабочий вариант сразу окончательный вариант таблицы разделов.
Arduino IDE
При изменении таблицы разделов в Arduino IDE (например вы выбрали в настройках платы другую таблицу или создали свою) выберите опцию Erase All Flash Before Sketch Upload в настройках платы. Но будьте осторожны – это нужно сделать только один раз при изменении таблицы разделов. При следующей прошивке эту опцию необходимо отключить.
ESP-IDF
Для очистки flash-памяти выполните команду:
idf.py erase-flash
или с указанием COM-порта:
idf.py -p <COM_PORT> erase_flash
После этого можно прошивать устройство с новой таблицей разделов, как обычно (командой flash).
Но можно прошить только новую таблицу разделов отдельной командой:
idf.py partition-table-flash
Стандартные таблицы разделов
Как я уже говорил, делать свою “разбивку” flash-памяти – не обязательно. Из коробки и Arduino core, и ESP-IDF предоставляет таблицы разделов “по умолчанию”.
Разделы для Arduino
Фреймворк Arduino core for ESP32 предоставляет вам большой набор готовых таблиц, из которых вы можете подобрать себе на любой вкус и кошелек. Например таблицы для классического ESP32 выглядят так:
Таблица по умолчанию Default 4MB with SPIFFS выглядит следующим образом:
# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x140000, app1, app, ota_1, 0x150000,0x140000, spiffs, data, spiffs, 0x290000,0x160000, coredump, data, coredump,0x3F0000,0x10000,
Список таблиц для других серий ESP32 вы можете найти здесь: [Настройка Arduino IDE для работы с ESP32]
Разделы по умолчанию для ESP-IDF
Для ESP-IDF из коробки доступны только две таблицы разделов: Single factory app, no OTA и Factory app, two OTA definitions. Вы вполне можете воспользоваться одним из этих двух вариантов и не “делать себе моск”.
Single factory app, no OTA
Одно приложение, без OTA разделов, без файловых систем и прочего. Почти самая простая структура:
Эта таблица занимает на FLASH-памяти только 1.1 MB, остальное тупо не используется:
Не самая оптимальная таблица.
Factory app, two OTA definitions
Одно “заводское “приложение плюс два OTA раздела для обеспечения возможности обновления прошивки по воздуху.
Здесь немного интереснее, память используется уже полностью, но опять же – не совсем оптимально, phy можно выкинуть, за счет этого немного подрастет nvs. При желании и от factory можно избавится – я собственно так и делаю.
Создаем свою таблицу разделов
Я лично предпочитаю использовать “свою” кастомную таблицу разделов. Почему? Просто я не люблю выбрасывать деньги на ветер (а кто любит?) свободное пространство на flash в пустоту, ибо на мой взгляд, встроенные в ESP-IDF варианты далеки от идеальных. Да и надо то одно, то другое.
Давайте создадим свою собственную таблицу разделов. Я лично исхожу из следующих принципов:
- Учитывая вышесказанное, таблицу разделов начинаем с адреса 0x9000. Как обычно и ничего нового.
- В моих устройствах используется технология OTA, потому мне нужно 2 раздела
ota_0иota_1. Создавать их больше двух – не вижу в этом особого смысла. За несколько лет зверских и бесчеловечных экспериментов над бедными и несчастными ESP мне так и не удалось добиться того, чтобы убить обе прошивки сразу. Но какие наши годы! Попытки не прекращаются. - Раздел
factoryвыкидываем – я лично его не использую. Зачем? Хранить там когда-то прошитую версию, которая через несколько обновлений через OTA безнадежно устареет? Такое себе… Впрочем – на вкус и цвет фломастеры разные. - Раздел
phyтоже сразу в топку. Я не выпускаю устройства на конвейере, поэтому оно мне без надобности. - Раздел
nvs– обязателен! Причем документация рекомендует использовать два раздела (системный и прикладной) – так и сделаем, заодно и смещение до 64К выровняем. - Есть смысл отделить 64К для
coredump– может понадобится в сложных случаях. А случаи бывают разные. - Есть идея хранить bundle корневых сертификатов для TLS в отдельном разделе. В этом случае можно “по быстрому” обновить этот самый bundle через OTA, не затрагивая саму прошивку. Но операция довольно рискованная, поэтому лучше иметь “запасной аэродром” в отдельном разделе, прошитый с “завода”, если что-то пойдет не так. Размера 64К по моим расчетам должно хватить.
- И в заключении – иногда может пригодится ФС, например spiffs – для хранения шаблонов web-страниц.
Самое сложное в создании своей таблицы – считать смещения разделов. При этом нужно помнить, что разделы app выравниваются до 64К, а остальные до 4К. И при этом нужно следить, чтобы один раздел не наложился на другой. Также нужно следить за тем, чтобы при выравнивании не оставалось неиспользуемого пространства. И считать все это нужно в hex-числах.
Итак, несколько моих вариантов: можете использовать их напрямую, можете как основу для своих, можете не использовать вовсе – только как примеры.
4MB FLASH: 2 OTA x 1.9MB + NVS 32+52KB
Подойдет для “больших” приложений, без файловых систем и удаленной отладки
- 2 OTA раздела по 1,9MB
- 2 NVS раздела 32 KB (системный) и 52 KB (прикладной)
# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, app0, app, ota_0, 0x20000, 0x1f0000, app1, app, ota_1, 0x210000, 0x1f0000,
4MB FLASH: 2 OTA x 1.9MB + NVS 32+52KB + coredump 64KB
В этом варианте добавлен раздел coredump со стандартным размером 64K для удаленной отладки. Из-за этого размер app разделов немного уменьшился – на 32 КБ каждый:
# ESP-IDF Partition Table # 4MB FLASH (0x400000): 2 OTA + 2 NVS (sys+app) + coredump # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, app0, app, ota_0, 0x20000, 0x1e0000, app1, app, ota_1, 0x200000, 0x1e0000, coredump, data, coredump, 0x3e0000, 0x10000,
4MB FLASH: 2 OTA x 1.9MB + NVS 32+52KB + 2 CERTS x 64KB + coredump 64KB
К предыдущему варианту здесь я добавил ещё два раздела certs_factory и certs_app. В первый я прошью список сертификатов через кабель (один раз), второй – основной раздел для сертификатов, его можно будет обновить через OTA, удаленно. Если что-то пойдет не так, и он будет поврежден – всегда останется резервный вариант.
Для этих разделов использован custom subtype 0x40 и 0x41:
# ESP-IDF Partition Table # 4MB FLASH (0x400000): 2 OTA + 2 NVS (sys+app) + 2 cert bundle + coredump # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, certs_factory, data, 0x40, 0x20000, 0x18000, certs_app, data, 0x41, 0x38000, 0x18000, app0, app, ota_0, 0x50000, 0x1d0000, app1, app, ota_1, 0x220000, 0x1d0000, coredump, data, coredump, 0x3f0000, 0x10000,
4MB FLASH: 2 OTA x 1.7MB + NVS 32+52KB + 2 CERTS x 64KB + SPIFFS 320KB + coredump 64KB
Теперь добавим небольшую файловую систему SPIFFS или FAT или LittleFS. Например чтобы хранить шаблоны web-интерфейса.
У меня получился такой вариант:
# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, certs_factory, data, 0x40, 0x20000, 0x10000, certs_app, data, 0x41, 0x30000, 0x10000, app0, app, ota_0, 0x40000, 0x1b0000, app1, app, ota_1, 0x1f0000, 0x1b0000, spiffs, data, spiffs, 0x3a0000, 0x50000, coredump, data, coredump, 0x3f0000, 0x10000,
8MB FLASH: 2 OTA x 3.1MB + NVS 32+52KB + 2 CERTS x 256KB + SPIFFS 1024KB + coredump 128KB
Для FLASH размером 8MB можно увеличить размеры всех разделов, кроме NVS:
# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, certs_factory, data, 0x40, 0x20000, 0x40000, certs_app, data, 0x41, 0x60000, 0x40000, app0, app, ota_0, 0xa0000, 0x320000, app1, app, ota_1, 0x3c0000, 0x320000, spiffs, data, spiffs, 0x6e0000, 0x100000, coredump, data, coredump, 0x7e0000, 0x20000,
16MB FLASH: FACTORY 4MB + 2 OTA x 4.0MB + NVS 32+52KB + 2 CERTS x 256KB + FATFS 3.3MB + coredump 128KB
Гуляем на все:
# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags otadata, data, ota, 0x9000, 0x2000, nvs, data, nvs, 0xb000, 0x8000, nvs_app, data, nvs, 0x13000, 0xd000, certs_factory, data, 0x40, 0x20000, 0x40000, certs_app, data, 0x41, 0x60000, 0x40000, factory, app, app, 0xa0000, 0x400000, ota_0, app, ota_0, 0x4a0000, 0x400000, ota_1, app, ota_1, 0x8a0000, 0x400000, fatfs, data, fat, 0xca0000, 0x340000, coredump, data, coredump, 0xfe0000, 0x20000,
Проверка созданной таблицы разделов
Перед тем, как подключать только что созданную таблицу разделов – неплохо бы её проверить. Это позволит выявить наложения разделов друг на друга или иные проблемы.
По большому счету это делать не обязательно, так как при первой же сборке проекта система сборки сделает это самостоятельно.
Вы можете проверить свой CSV-файл с помощью инструмента gen_esp32part.py, конвертировав его в бинарный формат и сразу отобразив содержимое.
python $IDF_PATH/components/partition_table/gen_esp32part.py <ваш файл разделов>.csv binary_partitions.bin
Потом можно отобразить содержимое только что созданного двоичного файла разделов:
python $IDF_PATH/components/partition_table/gen_esp32part.py binary_partitions.bin
Вы должны получить вывод на экран для вашей таблицы разделов, например:
Partition table binary generated. Contents: ******************************************************************************* # ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags otadata,data,ota,0x9000,8K, nvs,data,nvs,0xb000,32K, nvs_app,data,nvs,0x13000,52K, certs_factory,data,64,0x20000,96K, certs_app,data,65,0x38000,96K, ota_0,app,ota_0,0x50000,1856K, ota_1,app,ota_1,0x220000,1856K, coredump,data,coredump,0x3f0000,64K, *******************************************************************************
Инструмент автоматически выполняет верификацию таблицы (Verifying table…) при конвертации в двоичный код. Если в вашей таблице есть ошибки (например, перекрывающиеся разделы, неверные смещения или превышение размера flash), gen_esp32part.py сообщит об ошибке ещё до прошивки.
Подключение таблицы разделов к проекту ESP-IDF
Хорошо, файл с описанием разделов вы создали, что дальше?
Arduino IDE
Создайте CSV-файл с вашей таблицей разделов, как это описано выше. Затем назовите его partitions.csv (только так и никак иначе) и поместите в папку со скетчем, где находится ваш основной .ino файл. Затем в меню Arduino IDE выберите опцию Инструменты → Partition Scheme → Custom.
Если перед этим в ESP32 была прошита другая таблица разделов, то дополнительно выберите опцию Erase All Flash Before Sketch Upload в настройках платы. Но будьте осторожны – это нужно сделать только один раз при первом подключении вашего файла к проекту (или при его изменении).
ESP-IDF
Создайте CSV-файл с вашей таблицей разделов, как это описано выше. Далее запускаем menuconfig любым удобным способом и ищем раздел Partition Table → Partition Table. Он находится в корневом разделе. В нем выберите опцию “Custom partition table CSV“:
После того, как мы выбрали пункт, указывающий на то, что мы хотим всё сломать настроить своими руками, необходимо указать имя файла, который мы создали:
Ну вот, собственно и всё. Следующая сборка будет уже с новой таблицей разделов. Только не забудьте, что перед записью новой структуры разделов желательно стереть весь “диск” целиком.
PlatformIO
Для PlatformIO немного сложнее: дабы PlatformIO “увидел” этот файл, нужно указать его в специальном пункте файла platformio.ini, по аналогии с embed files:
Вот теперь ваш проект должен скомпилироваться с новыми разделами!
GUI-редактор таблицы разделов ESP IDE
Расширение ESP-IDF для Visual Studio Code (Espressif IDE) имеет встроенный редактор таблицы разделов, который можно вызвать командой ESP-IDF Open Partition Table Editor UI:
С помощью него можно создать или отредактировать кастомную таблицу разделов, не прибегая к ручному редактированию CSV-файлов. Однако этот редактор не умеет сам вычислять смещения – все циферки вам все равно придется вычислять и вводить вручную.
Важно! Прежде чем вы сможете отредактировать таблицу разделов с помощью данного редактора – необходимо предварительно выбрать в menuconfig режим “
Custom partition table CSV” (как это описано в предыдущем разделе) и указать имя файла. Причем сам файл может и не существовать – редактор создаст его самостоятельно.
В этом редакторе вы можете сразу же скомпилировать созданную таблицу (с валидацией) и прошить её на flash-память с помощью кнопок в правом верхнем углу редактора.
Ссылки
-= Каталог статей (список по разделам) =- -= Архив статей (плитки, все подряд) =-















добрый. наверно опечатка строка:
“Четыре мегабайта – это 4194304 байт или 0x40000 в HEX формате.”
и ниже показываете калькулятор где не 40 000, а 40 0000 (группировка страная но видно что 400 тыщ).. да и по суммам не сходится.. должно быть 400 тыщ, а не 40… иначе сложно в 40 уместить раздел под ОТА 180 тыщ )
Конечно же, вы правы. Благодарю за внимательность. Поправил.
спасибо что разжевали на «великом и могучем». несколько дней ломал голову как это всё работает и для чего нужны эти разделы. «не влезала» программа при попытке загрузить в плату из платформио. единственное так и не понял как смещения считаются. но я думаю хватит готовой таблицы )
Спасибо. Смещения считаются по самым простым правилам математики – сложения и вычитания. Одна тонкость – в шестнадцатеричном выражении. Современный калькулятор Win10 имеет режим программиста, с ним гораздо проще.
Этого не нашел )
<<< NVS пока что перекрывает все мои потребности. Поэтому я отдаю место под NVS по максимуму. Зачем так много? Это станет понятно потом, когда я расскажу, как устроен и работает этот раздел.
Смотрите следующую статью про NVS…