Esp32 узнать количество памяти
Вторая статья из цикла статей, посвященных контроллеру ESP32, подготовленных инженерами Espressif, рассказывает о том, как дать возможность пользователю сконфигурировать контроллер для работы в домашней сети, где хранить настройки и как осуществить сброс контроллера в заводское состояние
В предыдущей статье мы жестко задали учетные данные Wi-Fi сети в прошивке контроллера. Конечно, такой подход нельзя использовать в конечном продукте.
В рамках этой статьи будет показано, как изменить прошивку таким образом, чтобы конечный пользователь мог настроить учетные данные своей сети Wi-Fi в работающем устройстве. Кроме того, мы реализуем функционал «Сброс к заводским настройкам», который позволит удалить пользовательские данные из устройства. Исходный код для этой статьи приведен в папке 4_network_config/ проекта esp-jumpstart.
Как видно на этом рисунке, на этапе настройки сети конечный пользователь обычно использует свой смартфон для безопасной настройки учетных данных Wi-Fi сети на устройстве. Как только устройство получит эти учетные данные, оно сможет подключиться к домашней сети Wi-Fi.
Рис. 1. Процесс настройки сети
Для передачи учетных данных можно использовать несколько различных каналов. В проекте ESP-Jumpstart реализована поддержка следующих механизмов передачи данных:
- SoftAP
- Bluetooth с низким энергопотреблением (BLE)
У каждого из них есть свои плюсы и минусы. "Лучшего" способа сделать это не существует, некоторые разработчики выбирают один из них, другие - другой, в зависимости от того, что они ценят больше.
Если хочется комфорта
Если Вы хотите трогать файлы и видеть информацию о свободном пространстве, то скачайте скетч BRIDGE и прошейте им своё устройство.
Так же скачайте и скомпилируйте кроссплатформенный файловый менеджер A-Explorer (рисунок 3). На GitHub бинарные файлы вскоре будут лежать в папке bin.
Рисунок 3, a. Файловый менеджер A-Explorer под macOS
Рисунок 3, б. Файловый менеджер A-Explorer под Windows
Данный файловый менеджер позволит узнать информацию о свободном пространстве, загружать/выгружать/удалять файлы. Имеется индикация прогресса выполнения операции.
Как видите по рисунку 3 плагин разметил приблизительно 1,38 МБ памяти под SPIFFS.
Настройка модуля
В приведенном выше на несколько абзацев коде мы в первой строке инициализируем модуль конфигурации. Для инициализации должна использоваться структура конфигурации, пример которой приведен ниже:
- Scheme: Выбирает транспорт, который будет использоваться модулем настройки для конфигурации. Возможные значения SoftAP (wifi_prov_scheme_softap) или BLE (wifi_prov_scheme_ble).
- Scheme Event Handler: Определяет обработчик событий, характерный для выбранной схемы.
Обычно он используется только для освобождения памяти после завершения конфигурирования сети.
После вызова функции инициализации и проверки отсутствия сохраненных данных настроек сети в памяти, выполняется собственно запуск менеджера конфигурации:
/* Start provisioning service */
wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key);
Давайте теперь рассмотрим параметры, используемые при вызове этого метода API:
Давайте поговорим об использовании
К сожалению, из коробки память микроконтроллера не размечена под SPIFFS, для того чтобы разметить, необходимо воспользоваться плагином ESP32FS для среды разработки Arduino IDE.
После того, как плагин скачен – его необходимо установить:
- Убедитесь, что у Вас установлена новейшая версия среды разработки Arduino IDE и драйвера для Вашего устройства на ESP32. У меня M5Stack драйвера CP210X я скачиваю по этой ссылке;
- Скопируйте скаченную папку tool со вложенным в неё плагином в папку /Arduino/tools/ESP32FS/;
- В macOS папка расположена по адресу ~/Documents/Arduino/;
- Перезагрузите компьютер и проверьте в среде разработки в меню Инструменты (Tools) появится пункт ESP32 Sketch Data Upload (рисунок 2) – значит Вы всё выполнили правильно;
Рисунок 2. Меню Инструменты (Tools)
- Обратите внимание на папку data, находящуюся рядом со скетчем. Все файлы, расположенные в данной папке, будут загружены в память устройства при форматировании;
- Смело выбираем указанный пункт и дожидаемся окончания форматирования области памяти. Обратите внимание на то, что другие участки памяти затронуты НЕ будут, а значит микропрограмма останется в памяти устройства и будет работать. Аналогично и со скетчем, когда он будет скомпилирован в микропрограмму и загружен в устройство – файловая система затронута не будет.
Доказательство владения
Когда пользователь запускает новое интеллектуальное устройство, контроллер поднимает свою сеть (BLE или SoftAP) для конфигурации. Как убедиться, что устройство настраивает именно владелец устройства, а не его соседи?
В устройство можно заложить логику работы, которая потребует, что бы пользователь, настраивающий устройство, предоставил доказательство того, что он действительно владеет устройством, которое он настраивает. Доказательство владения может быть предоставлено путем выполнения каких-либо физических действий на устройстве или путем ввода некоторого уникального случайного ключа, который входит в комплект поставки, или путем ввода кода, отображенного на экране устройства, если оно, конечно, оборудовано таковым.
При изготовлении каждое устройство может быть запрограммировано с помощью уникального случайного ключа. Этот ключ затем может быть предоставлен унифицированному модулю конфигурации в качестве опции подтверждения владения. Когда пользователь настраивает устройство с помощью приложения на телефоне, введенный пользователем ключ передается на устройство. Модуль конфигурации проверяет, что переданный и сохраненный в прошивке ключи совпадают, а затем подтверждает конфигурацию.
SoftAP
При использовании механизма SoftAP контроллер запускает собственную точку доступа Wi-Fi. Пользователь может подключить свой смартфон к этой сети и использовать созданное соединение для передачи учетных данных Wi-Fi в контроллер. Многие устройства на рынке сегодня используют такой механизм. В этом случае для настройки сети пользователь должен:
- переключить Wi-Fi своего телефона на сеть, поднятую розеткой;
- запустить приложение на телефоне;
- ввести в приложении учетные данные домашней сети Wi-Fi, которые затем будут переданы в розетку через соединение SoftAP.
С точки зрения пользовательского опыта, первый шаг требует, чтобы пользователь изменил настройки Wi-Fi сети своего телефона. Это может сбивать с толку некоторых пользователей. Изменение сети Wi-Fi программно с помощью приложения для телефона не всегда возможно (iOS и некоторые варианты Android не позволяют это делать приложениям). Но преимущество такого метода состоит в том, что он очень надежен (SoftAP - это просто реализация Wi-Fi сети) и не требует большого количества дополнительного кода (и занимаемого места) в прошивке устройства.
При использовании Bluetooth с низким энергопотреблением (BLE) ваша розетка будет видна как BLE устройство. Телефоны, находящиеся поблизости, смогут увидеть это устройство и предложить пользователю установить с ним BLE-соединение. Затем это соединение будет использоваться для передачи учетных данных в контроллер. В таком варианте подключения пользователю не нужно задумываться о переключении между сетями Wi-Fi. Кроме того, как iOS, так и Android позволяют телефонному приложению сканировать находящиеся поблизости устройства BLE и подключаться к ним через приложение. Это существенно облегчает взаимодействие с конечным пользователем.
Однако одним из побочных эффектов использования конфигурации сети через BLE является то, что этот вариант работы потребует кода для реализации Bluetooth соединения. Это означает, что ваши требования к флэш-памяти увеличатся, поскольку увеличится размер прошивки. В режиме конфигурации сети BLE также будет потреблять оперативную память до завершения настройки сети.
Прежде чем углубляться в детали рабочего процесса настройки сети, давайте попробуем выполнить настройку в демо приложении (см. каталог 4_network_config/).
Дополнительные детали
В предыдущей главе было упомянуто, что учетные данные Wi-Fi хранятся в NVS. NVS - это программный компонент, который поддерживает постоянное энергонезависимое хранение пар ключ-значение. Эта информация остается доступной после перезагрузки и отключения питания. NVS использует специальный раздел флэш-памяти для хранения этой информации.
NVS спроектирован таким образом, чтобы быть устойчивым к повреждению метаданных при сбое питания. Он также заботится о выравнивании износа флэш-памяти, распределяя записи по разделу NVS.
Разработчики приложений также могут использовать NVS для хранения любых дополнительных данных, которые вы хотите сохранить как часть прошивки вашего приложения. Любые типы данных, такие как целые числа, строки с нулевым символом в конце и двоичные объекты, могут храниться в памяти NVS. Этот раздел может использоваться для хранения любых пользовательских настроек вашего продукта. Для чтения и записи значений в NVS используются следующие функции.
/* Store the value of key 'my_key' to NVS */
nvs_set_u32(nvs_handle, "my_key" , chosen_value);
/* Read the value of key 'my_key' from NVS */
nvs_get_u32(nvs_handle, "my_key" , & chosen_value);
Одним из самых распространенных функционалов, который встречается практически в любом настраиваемом пользователем продукте, является сброс до заводских настроек. В нашем случае, если пользовательская конфигурация сохранена в NVS, как обсуждалось выше, восстановление заводских настроек может быть достигнуто простым стиранием раздела NVS.
Обычно это действие вызывается долгим нажатием кнопки, доступной на устройстве. Это можно легко реализовать с помощью функции iot_button_().
В рассматриваемом сейчас приложении 4_network_config функционал обработки длительного нажатия можно повесить на ту же кнопку, что занимается переключением выхода.
/* Register 3 second press callback */
iot_button_add_on_press_cb(btn_handle, 3 , button_press_3sec_cb, NULL);
Этот код приведет к вызову коллбэк функции button_press_3sec_cb () всякий раз, когда интервал между нажатием и отпусканием кнопки, связанной с btn_handle, превышает 3 секунды. (Инициализация btn_handle была сделана в предыдущей статье).
В самой функции обратного вызова нужно записать следующий код:
static void button_press_3sec_cb(void * arg)
<
nvs_flash_erase();
esp_restart();
>
Этот код сначала стирает все содержимое NVS, а затем выполняет перезагрузку контроллера. Поскольку NVS теперь не содержит информации, при очередной загрузке устройства будет запущен режим конфигурирования.
Теперь пользователь может настроить контроллер через приложение на телефоне для работы в своей домашней сети. После сохранения настроек розетка подключится к заданной сети. У пользователя также есть возможность стереть эти настройки длительным нажатием кнопки на устройстве.
На данный момент функциональность розетки и функциональность подключения разделены. В следующей статье будет рассказано, как контролировать состояние розетки через облако.
Post by megabite » Sat Dec 30, 2017 8:40 pm
I just got my ESP32 dev board in the mail a few days ago, and I am trying it out with a few things.
One thing that baffles me is that it apparently doesn't have 16 megabyte of flash memory as advertised.
It's an ESP32 WROOM 32 dev board, FCC ID: 2AC7Z-ESPWROOM32. Wikipedia says that this type of board has 4 MiB of flash memory. Which is already not really what the board was supposed to have as per the description from where I bought it.
And now when I try to upload sketches using the Arduino IDE, it tells me that maximum program memory is 1.310.720 bytes, and that the maximum of dynamic memory is 294.912 bytes, which isn't even 2 MB combined. I would suspect that some of the board's memory is "non-negotiable" as it is needed for the ESP32 core code, but still, does my board really not have the 16 megabyte of flash that it was advertised as??
Post by WiFive » Sun Dec 31, 2017 9:16 am
Wroom32 has 4MByte by default but it is possible they used custom order to get 16MB. Use esptool to check flash
Post by megabite » Sun Dec 31, 2017 12:18 pm
thanks for the answer, but I think I still need a little help here.
What exactly do I type into the esptool prompt to get the actual flash size? When I type in check_flash, it gives me a list of positional and optional argument options, but then when I try to use those, somehow I can't type them in without getting too few/too many arguments errors.
Also, if my ESP32 does turn out to have 16 MB of flash, what do I put into my default.csv and boards.txt files? How do I alter them?
At the moment, this is what the default.csv contains:
And this is what (part of) the boards.txt looks like:
esp32.upload.tool=esptool
esp32.upload.maximum_size=1310720
esp32.upload.maximum_data_size=294912
esp32.upload.wait_for_upload_port=true
esp32.build.mcu=esp32
esp32.build.core=esp32
esp32.build.variant=esp32
esp32.build.board=ESP32_DEV
esp32.build.f_cpu=240000000L
esp32.build.flash_size=4MB
esp32.build.flash_freq=40m
esp32.build.flash_mode=dio
esp32.build.boot=dio
esp32.build.partitions=default
esp32.menu.FlashMode.qio=QIO
esp32.menu.FlashMode.qio.build.flash_mode=dio
esp32.menu.FlashMode.qio.build.boot=qio
esp32.menu.FlashMode.dio=DIO
esp32.menu.FlashMode.dio.build.flash_mode=dio
esp32.menu.FlashMode.dio.build.boot=dio
esp32.menu.FlashMode.qout=QOUT
esp32.menu.FlashMode.qout.build.flash_mode=dout
esp32.menu.FlashMode.qout.build.boot=qout
esp32.menu.FlashMode.dout=DOUT
esp32.menu.FlashMode.dout.build.flash_mode=dout
esp32.menu.FlashMode.dout.build.boot=dout
esp32.menu.FlashFreq.80=80MHz
esp32.menu.FlashFreq.80.build.flash_freq=80m
esp32.menu.FlashFreq.40=40MHz
esp32.menu.FlashFreq.40.build.flash_freq=40m
esp32.menu.FlashSize.4M=4MB (32Mb)
esp32.menu.FlashSize.4M.build.flash_size=4MB
esp32.menu.FlashSize.2M=2MB (16Mb)
esp32.menu.FlashSize.2M.build.flash_size=2MB
esp32.menu.FlashSize.2M.build.partitions=minimal
Контроллер ESP32 имеет всего 512КБ оперативной памяти, и в сложных проектах разработчик может столкнуться с ее нехваткой. В статье рассказано о встроенных программных инструментах ESP IDF, которые позволят найти проблемные точки и оптимизировать их
Контроллер ESP32 имеет всего 512КБ оперативной памяти, и в сложных проектах разработчик может столкнуться с ее нехваткой. В статье рассказано о встроенных программных инструментах ESP IDF, которые позволят найти проблемные точки и оптимизировать их.
Контроллер ESP32 имеет 512 КБ памяти SRAM. Хотя этот объем может показаться относительно небольшим, при грамотном использовании он может предоставить множество возможностей для разработчика.
Исходный код приложения обычно содержит ряд файлов и библиотек, и компоновщик в своей работе извлекает из этих компонентов различные функции и переменные. Компоновщик обычно оптимизирует объекты, которые не используются (или на которые не ссылаются) в готовой прошивке. Таким образом, в зависимости от того, что вы делаете в своем приложении, вклад различных компонентов в использование памяти меняется.
В состав фреймворка ESP IDF входит утилита idf_size.py, которая позволит оценить использование памяти, чтобы вы могли идентифицировать и оптимизировать проблемные точки. Утилита связана со скриптами сборки, поэтому вы можете напрямую запускать команду make target, чтобы увидеть потребление памяти, не запоминая других команд.
Давайте посмотрим, как можно использовать эту утилиту, чтобы оценить эффективность использования памяти.
Память, выделенная под конкретные компоненты
Первое, что нужно сделать при анализе распределения памяти, это посмотреть, какое влияние каждый из используемых компонентов оказывает на окончательный образ прошивки. Это можно сделать, указав цель size-components для системы сборки. Выполнение этой команды после сборки приложения examples/wifi/power_save дает следующий результат:
$ make IDF_PATH=~/work/idf size-components
Total sizes:
DRAM .data size: 14200 bytes
DRAM .bss size: 23224 bytes
Used static DRAM: 37424 bytes ( 143312 available, 20.7% used)
Used static IRAM: 62344 bytes ( 68728 available, 47.6% used)
Flash code: 368546 bytes
Flash rodata: 65916 bytes
Total image size:~ 511006 bytes (.bin may be padded larger)
Per-archive contributions to ELF file:
Archive File
DRAM.data
& .bss
IRAM
Flash code
& rodata
Total
На экране видна итоговая информация об объеме, занимаемом всеми компонентами прошивки. Кроме того, в таблице предоставлена подробная информация по каждому из компонентов:
- data: это размер секции .data приложения. В этой секции размещаются предварительно инициализированные данные и константы.
- bss: это размер секции .bss. Здесь размещаются любые глобальные или статически определенные переменные и объекты, которые инициализируются нулями при загрузке.
- IRAM: это размер секции кода ( .text ), которую необходимо загрузить в IRAM. Обратите внимание, что большая часть кода может быть выполнена непосредственно из флэш-памяти (XIP), без необходимости загрузки его в IRAM. Как правило, сюда попадает код, который выполняется в контексте прерывания или непосредственно обращается к флэш-памяти для чтения/ записи.
- Flash Code: это размер секции кода ( .text ), которая размещается во флэш-памяти и выполняется непосредственно оттуда. Большая часть вашего раздела кода окажется именно в этом столбце.
- Flash rodata: здесь показаны данные, предназначенные только для чтения и используемые прошивкой (строки, статически инициализированные и неизменяемые массивы). Поскольку доступ к флэш-памяти возможен во время выполнения программы, нет необходимости загружать секцию в память.
- Total: общий используемый объем памяти для этого компонента.
Конечно, особое внимание нужно уделить размерам разделов IRAM и DRAM, так как именно объем SRAM является ограничивающим фактором (512 КБ) относительно флэш-памяти (порядка 2–8 МБ).
Поиск проблемной сущности
Допустим, вы узнали, что один из используемых вами компонентов потребляет гораздо больше памяти, чем должен. Вы можете изучить проблему глубже, чтобы определить, какая сущность в этом компоненте больше всего влияет на объем используемой памяти. Это можно сделать, используя цель size-symbols для системы сборки. Например:
$ make IDF_PATH=~/work/idf size-symbols COMPONENT=soc
Total sizes:
DRAM .data size: 14200 bytes
DRAM .bss size: 23224 bytes
Used static DRAM: 37424 bytes ( 143312 available, 20.7% used)
Used static IRAM: 62344 bytes ( 68728 available, 47.6% used)
Flash code: 368546 bytes
Flash rodata: 65916 bytes
Total image size:~ 511006 bytes (.bin may be padded larger)
Symbols within the archive: libsoc.a (Not all symbols may be reported)
Symbols from section: .dram0.data
str1.4(605) __func__$3446(23) __func__$3425(21) rtc_clk_cpu_freq_value(20)
Section total: 669
Symbols from section: .dram0.bss
s_cur_pll(4) s_cur_freq(4)
Section total: 8
Symbols from section: .iram0.text
rtc_init(1020) rtc_clk_cpu_freq_set(472) rtc_clk_bbpll_set(380) rtc_clk_cal_internal(369) .iram1(282) rtc_clk_cpu_freq_get(172) rtc_clk_32k_bootstrap(170) rtc_clk_32k_enable_internal(149) rtc_clk_wait_for_slow_cycle(129) rtc_time_get(96) rtc_clk_cpu_freq_value(96) rtc_clk_cal(78) rtc_clk_xtal_freq_get(68) rtc_clk_slow_freq_get_hz(51) rtc_clk_apb_freq_get(50) rtc_clk_32k_enable(49) rtc_clk_fast_freq_set(46) rtc_clk_slow_freq_set(43) clk_val_is_valid(32) .iram1.literal(28) rtc_clk_apb_freq_update(23) rtc_clk_slow_freq_get(16) clk_val_to_reg_val(14) reg_val_to_clk_val(8)
Section total: 3841
Symbols from section: .iram0.vectors
Section total: 0
Symbols from section: .flash.text
Section total: 0
Symbols from section: .flash.rodata
soc_memory_regions(704) soc_memory_types(320) str1.4(159) soc_reserved_regions(48) soc_reserved_region_count(4) soc_memory_region_count(4)
Section total: 1239
Для получения дополнительной информации по использованию памяти различными сущностями компонента в командной строке make был использован дополнительный параметр COMPONENT = . Например, в приведенном выше примере была запрошена информация для компонента «soc».
В результатах вывода команды виден вклад каждой сущности (функции, переменной или объекта) этого компонента в общий размер прошивки. Обратите внимание, что размер каждой функции виден в секции .iram0.text, а, например, массивы soc_memory_types и soc_memory_regions (определенные в soc_memory_layout.c как «const»), помещены во флэш-память, поскольку они предназначены только для чтения.
Результат работы команды может быть эффективно использован для точного определения того, какие части ваших компонентов вносят заметный вклад в использование оперативной памяти контроллера, что позволит вам сосредоточиться на эффективной оптимизации именно этих компонентов.
Дополнительные материалы:
ESP8266EX - маломощное высокоинтегрированное решение Wi-Fi, разработанное на основе 32-разрядного микропроцессора Tensilica L106 для мобильных устройств, носимой электроники и для приложений IoT, обеспечивающее низкое энергопотребление за сч?т использования нескольких патентованных технологий.…
Базовый модуль, использующий высокопроизводительную микросхему ESP32-D0WDQ6 с двухъядерным процессором и максимальной рабочей частотой до 240 МГц. Микросхема ESP32-D0WDQ6 работает под управлением freeRTOS и использует стек LwIP, ESP32-D0WDQ6, 32Mbits SPI flash, UART Mode
ESP32-WROVER-I [4MB] - SMD Module ESP32-WROVER, ESP32-D0WDQ6, 1.8V 64Mbits PSRAM, 32Mbits SPI flash, IPEX Antenna connector
ESP32-WROVER - мощный высокопроизводительный модуль общего назначения со встроенным микроконтроллерным ядром и с поддержкой стандартов связи Wi-Fi+BT+BLE, предназначенный для широкого ряда приложений с экономичным энергопотреблением.
Wi-Fi+BT+BLE-модуль, построенный на базе одноядерной микросхемы ESP32-S0WD. Как отмечалось выше, ESP32-S0WD – младший представитель семейства ESP32. Несмотря на это, ESP32-SOLO-1 может применяться в широком спектре приложений – от малопотребляющих датчиков (наиболее оптимальный вариант), до приложений с беспроводной передачей звука, ESP32-S0WD, Single Core, 32Mbits SPI flash, UART Mode
Это может оказаться полезным, когда скетч работает некорректно, и трудно определить причину ошибки. Ниже на примере показано, как определить количество свободной памяти RAM вызовом функции memoryFree.
Пользовательская функция memoryFree использует системные переменные для вычисления количества свободной оперативной памяти RAM. Обычно системные переменные невидимы - они создаются компилятором для собственного использования (для управления внутренними ресурсами).Количество свободной памяти может меняться с течением времени, пока работает Ваша программа. Очень важно удостовериться, что Вы не тратите больше памяти, чем имеется в наличии у системы.Вот несколько основных причин потребления памяти RAM:
• Когда Вы инициализируете константы:
• Когда Вы декларируете глобальные переменные:
• Когда делаете вызов функции:
• Когда динамически выделяете память:
Объект String системы Arduino использует динамическое выделение памяти для строк. Вы можете проверить это, если добавите в начало кода примера определение строки String s = "\n";, и затем добавите в код loop перед задержкой строки:
После запуска этого варианта скетча Вы увидите, что количество памяти уменьшается, потому что каждая прокрутка цикла loop увеличивает размер строки. В какой-то момент память переполнится, и программа перестанет работать. Поэтому не увеличивайте размер строк сверх необходимого, и следите за их размером. Также будьте особенно внимательны с кодом, который использует динамическое выделение памяти. Не пишите код, который динамически создает разное количество переменных в зависимости от некоторых параметров во время своей работы, потому что очень сложно бывает найти ошибки во время выполнения кода, связанные с переполнением памяти.
Также в библиотеках часто объявляются константы и глобальные переменные, о которых Вы можете не знать, но они также расходуют RAM. У библиотеки Serial, например, есть глобальный массив из 128 байт, который используется как буфер для приходящих последовательных данных. Только это использует одну восьмую от общего объема памяти старого Arduino на микроконтроллере ATmega168.
SPIFFS – (Serial Peripheral Interface Flash File System) файловая система флеш-памяти, подключаемой по последовательному периферийному интерфейсу. Простыми словами: есть микроконтроллер ESP32 (рисунок 1), у него есть встроенная перезаписываемая энергонезависимая NOR-память, в которой хранятся: настройки (Preferences), загрузчик (Bootloader), микропрограмма (скомпилированный скетч), файловая система (SPIFFS) и ещё что-нибудь, типа обновления "по воздуху" (OTA).
Рисунок 1. Функциональная блок-схема микроконтроллера ESP32
NOR-память – это такой вид энергонезависимой перезаписываемой памяти, который имеет достаточно высокую скорость считывания, относительно низкую скорость записи и стирания, в сравнении с типом памяти NAND. Встретить NOR-память большого объёма практически невозможно, обычно ограничиваются 128 МБ. В случае с ESP32 – четырьмя.
На сегодняшний день SPIFFS имеет некоторые недостатки недоработки , в их числе: отсутствие поддержки папок; не стек реального времени, поэтому одна и та же операция может занимать разное время; отсутствие возможности нахождения и исправления битых блоков. Если перечисленные недостатки для Вас некритичны, то продолжаем читать следующий пункт.
Кто такой этот BRIDGE?
BRIDGE – это скетч, а прежде всего одноимённая функция, которая работает с файловой системой SPIFFS и A-Explorer является графической оболочкой для неё. Последний отправляет ту или иную команду, а данная функция её обрабатывает на самом устройстве с использованием библиотек FS и SPIFFS. Давайте посмотрим, чего есть интересного в этих библиотеках.
Начнём с рассмотрения публичных методов класса SPIFFS:
Метод bool begin(bool formatOnFail=false, const char * basePath="/spiffs", uint8_t maxOpenFiles=10). Данный метод пытается инициализировать экземпляр класса. Первым аргументом принимает истину или ложь на тот случай, стоит ли форматировать файловую систему, если файловая система не отформатирована. Второй аргумент принимает путь, где будет располагаться корень файловой системы. Третий аргумент определят количество одновременно открытых файлов. Последние два параметра лучше оставить дефолтными и не менять их. Если файловая система отсутствует (не был использован плагин, приведённый выше). то функцию вернёт ложь.
Метод bool format() проверят отформатирована ли файловая система – возвращает истину, в противном случае – ложь.
Метод size_t totalBytes(). Такой метод возвращает size_t-число общего количества Байт размеченных под файловую систему.
Метод size_t usedBytes(). Этот метод возвращает size_t-число используемых Байт в файловой системе.
Метод void end(). Данный метод производит деинициализацию данного класса. После вызова данного метода другие методы вызывать бессмысленно.
В данном классе всё, ничего особо интересного нет. Давайте перейдём к классу FS и посмотрим, что оттуда нам может пригодиться.
Первое, что бросается в глаза, так это метод-инициализатор класса bool begin(). Данный метод не требует аргументов и вызывать его нет необходимости, т. к. мы будем использовать сразу следующий метод.
Метод File open(const char path, const char mode) и его брат File open(const String& path, const char* mode). Данные методы принимают по два аргумента первый из них символьный и строковый указатель на путь к файлу, а второй режим открытия, который может быть следующей константой:
FILE_READ – открыть только для чтения;
FILE_WRITE – открыть только для записи;
FILE_APPEND – открыть для дозаписи.
После того, как мы открыли файл, теперь можем произвести над ним какие-либо операции.
- Метод size_t write(uint8_t) позволяет записать в конец файла одно 8 битное беззнаковое целое число.
- Метод size_t write(const uint8_t *buf, size_t size) позволяет записывать ряд безнаковых целых чисел указанной длинны во втором аргументе.
- Метод int available() подсчитывает количество символов от конца до указателя.
- Метод int read() считывает из файла один символ и возвращает его в виде целого числа, при этом курсор смещается на единицу право.
- Метод size_t readBytes(char *buffer, size_t length) считывает символы в буфер, указатель на который получен первым аргументом, а количество символов, переданное вторым аргументом. Возвращает количество считанные символов.
- Метод String readString() cчитывет строку из файла.
- Метод int peek() работает аналогично методу int read(), только курсор остаётся на месте.
- Метод bool seek(uint32_t pos, SeekMode mode) и bool seek(uint32_t pos, SeekMode mode) устанавливает курсор в указанное место. Первым аргументом передают позицию, а вторым правило (SeekSet – установить курсор). Если успешно – возвращает истину, в противном случае – ложь.
- Метод size_t position() возвращает позицию курсора.
- Метод size_t size() возвращает размер файла в Байтах.
- Метод const char * name() возвращает имя файла.
- Метод const char * fullName() с учётом полного пути.
- Метод bool isFile() возвращает истину, если открытый объект является файлов. В противном случае – ложь.
- Метод bool isDirectory() возвращает истину, если открытый объект является папкой. В противном случае – ложь.
- Метод File openNextFile() возвращает указатель на следующий файл в корне, в противном случае NULL.
- Метод bool exists(const char* path) и bool exists(const String& path) принимает в качестве аргумента полное имя файла, и, если такой файл существует, то возвращает истину, в противном – ложь.
- Метод bool remove(const char* path) и bool remove(const String& path) пытается удалить файл, имя которого передано аргументом. В случае успеха возвращает истину, в противном случае – ложь.
- Метод bool rename(const char pathFrom, const char pathTo) и bool rename(const String& pathFrom, const String& pathTo); принимает полное имя файла первым аргументов, а вторым полное новое имя файла и производите переименование.
Да-да, можно взять эту функцию и запустить её в отдельном потоке в любом другом скетче
Спасибо большое за уделённое время! Буду рад, если данная статья принесёт Вам пользу.
Для пользователей ESP8266
ESP8266 поддерживает только инициализацию на основе SoftAP, так как у него нет встроенного Bluetooth. Для выполнения подключения используйте приложение ESP SoftAP Provisioning.
Espressif предоставляет модуль Unified Provisioning для помощи в настройке пользовательской сети. Когда этот модуль вызывается из исполняемого файла прошивки, он берет на себя весь процесс настройки пользовательских параметров (запуск/ остановка интерфейса softAP/ BLE, безопасный обмен учетными данными, их хранение для последующего использования и т. д.). Модуль обладает следующими возможностями:
Более подробно о входящих в состав инфраструктуры настройки контроллера компонентах можно получить по следующим ссылкам:
Код для вызова единой системы конфигурации через прошивку показан ниже:
wifi_prov_mgr_init(config);
if (wifi_prov_mgr_is_provisioned( & provisioned) != ESP_OK) <
return ;
>
if (provisioned != true) <
/* Start provisioning service */
wifi_prov_mgr_start_provisioning(security, pop,
service_name, service_key);
> else <
/* Start the station */
wifi_init_sta();
>
Компонент wifi_provisioning предоставляет оболочку для унифицированного интерфейса настройки. Обратите внимание на несколько моментов:
Эта последовательность команд гарантирует, что модуль конфигурации запускается только в том случае, если в памяти не найдены сохраненные настройки сети, а если настройки сети обнаружены, то запускается интерфейс станции Wi-Fi.
Унифицированный модуль конфигурации должен обрабатывать события интерфейса Wi-Fi. Следовательно, в обработчик событий нужно добавить вызов функции wifi_prov_mgr_event_handler, которая позаботится об этом:
esp_err_t event_handler(void * ctx, system_event_t * event)
<
wifi_prov_mgr_event_handler(ctx, event);
switch(event -> event_id) <
case SYSTEM_EVENT_STA_START:
.
.
.
Читайте также: