ESP-IDF: драйвер Wi-Fi |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Драйвером Wi-Fi поддерживаются следующие возможности: · 4 виртуальных Wi-Fi интерфейса: STA, AP, Sniffer и reserved. [Как написать приложение Wi-Fi] Обычно самый эффективный способ начать разрабатывать свое приложение Wi-Fi - выбрать пример, который больше всего похож на ваше будущее приложение, и портировать из него полезную часть в свой проект. Не обязательно прочитать эту документацию, но все-таки это настоятельно рекомендуется, особенно если вы хотите получить надежное приложение Wi-Fi. Эта статья (здесь приведен перевод документации [1]) является дополнением к документации Wi-Fi API / примерам. Здесь описываются принципы использования Wi-Fi API, ограничения текущей реализации Wi-Fi API, и наиболее общие промахи в использовании Wi-Fi. Также раскрываются некоторые подробности дизайна драйвера Wi-Fi. Примеры приложений Wi-Fi можно просмотреть и выбрать на GitHub [4]. Конфигурирование буфера. Если вы собираетесь изменить номер или тип буфера по умолчанию, то может быть полезным получить представление о том, как буфер выделяется / освобождается на пути распространения данных. На следующей диаграмме показан процесс в направлении передачи (TX): Рис. 1. Выделение буфера передачи (TX Buffer). Описание: · Приложение выделяет данные, которые нужно отправить. Следующая диаграмма показывает, как буфер выделяется/освобождается в направлении приема (RX): Рис. 2. Выделение буфера приема (RX Buffer). Описание: · Аппаратура Wi-Fi принимает пакет по радиоканалу, и помещает его содержимое в "Static Rx Buffer", которй также называется "RX DMA Buffer". Таблица 1. Конфигурация внутреннего буфера Wi-Fi.
Wi-Fi NVS Flash. Если разрешено Wi-Fi NVS flash, то все конфигурации Wi-Fi, установленные через Wi-Fi API, будут сохранены в flash, и драйвер Wi-Fi запустится с этими настройками во время следующего включения питания/перезагрузки. Однако приложение может выбрать запретить Wi-Fi NVS flash, если не требуется сохранять конфигурацию в постоянную память, или у пользователя есть собственное постоянное хранилище для настроек, или настройки не нужно сохранять по причине отладки, и т. д. Wi-Fi Aggregate MAC Protocol Data Unit (AMPDU). ESP32 поддерживает AMPDU как для приема, так и для передачи, и AMPDU может значительно улучшить производительность канала Wi-Fi. Примечание: обычно AMPDU должен быть разрешен. Запрещают AMPDU обычно делают для целей отладки. В моем случае запрет AMPDU дал выигрыш во времени подключения к Wi-Fi на 200 .. 400 мс. Инициализация Wi-Fi, установка соединения. Основные действия для этих процедур описаны во врезке "ESP32 Wi-Fi Station General Scenario". Диаграмма показывает "большой сценарий", который описывает некоторые малые сценарии в режиме станции Wi-Fi: Рис. 3. Пример сценариев событий, когда устройство работает в Station Mode. 1. Wi-Fi/LwIP Init Phase s1.1: Главная задача (main task) вызовет esp_netif_init(), чтобы создать LwIP core task и инициализировать связанный с LwIP рабочий контекст. s1.2: Main task вызывает esp_event_loop_create() для создания системой задачи обработки событий (system Event task) и и инициализирует callback-функцию событий приложения. В сценарии, показанном на диаграмме выше, callback-функция события приложения не делает ничего, кроме как перенаправляет событие в задачу приложения. s1.3: Main task вызывает esp_netif_create_default_wifi_ap() (для режима точки доступа) или esp_netif_create_default_wifi_sta() (для режима станции), чтобы создать экземпляр сетевого интерфейса по умолчанию, привязывающего станцию или точку доступа (AP) к стеку TCP/IP. s1.4: Main task вызывает esp_wifi_init() для создания задачи драйвера Wi-Fi (Wi-Fi driver task) и инициализирует драйвер Wi-Fi. s1.5: Main task вызывает API-функцию операционной системы для создания задачи приложения (application task). Шаги 1.1 ~ 1.5 представляют собой рекомендованную последовательность, которая инициализирует основанное на Wi-Fi/LwIP приложение. Однако это НЕ ОБЯЗАТЕЛЬНАЯ последовательность, т. е. например можно создать задачу приложения на шаге 1.1, и поместить другие операции по инициализации в задачу приложения. Кроме того, создание задачи приложения на фазе инициализации может быть нежелательным, если задача приложения зависит от сокетов. Вместо этого вы можете отложить момент создания задачи, пока не будет получен IP-адрес. 2. Wi-Fi Configuration Phase Как только драйвер Wi-Fi был инициализирован, вы можете начать его конфигурирование. В этом сценарии показан режим станции (т. е. устройство подключается к внешней точке доступа Wi-Fi), так что вам может понадобиться вызвать esp_wifi_set_mode(WIFI_MODE_STA) для конфигурации режима Wi-Fi в качестве станции. Вы можете вызвать другие API-функции esp_wifi_set_xxx APIs для конфигурирования разных настроек, таких как режим протокола (protocol mode), код страны (country code) и полоса пропускания (bandwidth). Подробности см. далее в разделе "Конфигурация ESP32-C3 Wi-Fi". Обычно драйвер Wi-Fi должен быть сконфигурирован перед установкой соединения Wi-Fi. Однако это не обязательно, т. е. вы можете сконфигурировать соединение Wi-Fi в любой момент, при условии успешной инициализации драйвера Wi-Fi. Однако, если конфигурация не нуждается в изменении после того, как соединение Wi-Fi установлено, то вы должны конфигурировать драйвер Wi-Fi на этой стадии, потому что API-функции конфигурации (такие как esp_wifi_set_protocol()) приведут к переподключению Wi-Fi, что может быть нежелательным. Если в menuconfig разрешена Wi-Fi NVS flash, то на этой фазе, или на последующих фазах, вся конфигурация Wi-Fi, будет сохранена в память flash. Когда на плату подано питание / происходит перезагрузка, вам не нужно конфигурировать драйвер Wi-Fi с нуля. Вам только нужно вызвать API-функции esp_wifi_get_xxx для извлечения конфигурации, которая была ранее сохранена во flash. Вы можете также конфигурировать драйвер Wi-Fi, если предыдущая конфигурация не та, которую вы хотели. 3. Wi-Fi Start Phase s3.1: Вызовите esp_wifi_start() для запуска драйвера Wi-Fi. s3.2: Драйвер Wi-Fi публикует событие WIFI_EVENT_STA_START в задачу событий (event task); затем event task выполнит общие действия и вызовет callback-функцию события приложения. s3.3: Callback-функция события приложения перенаправляет WIFI_EVENT_STA_START в задачу приложения (application task). Разработчики ESP-IDF рекомендуют вызывать здесь esp_wifi_connect(). Однако вы также можете вызвать esp_wifi_connect() на других фазах после возникновения события WIFI_EVENT_STA_START. 4. Wi-Fi Connect Phase s4.1: Как только была вызвана esp_wifi_connect(), драйвер Wi-Fi запустит внутренний процесс сканирования/соединения. s4.2: Если внутренний процесс сканирования/соединения был успешен, то генерируется событие WIFI_EVENT_STA_CONNECTED. В задаче событий (event task) в ответ на это запустится клиент DHCP, который в завершение запустит процесс получения IP-адреса по протоколу DHCP. s4.3: В упомянутом выше сценарии callback-функция событий приложения перенаправляет событие в задачу приложения. Обычно приложению ничего специально необходимого делать не надо, и вы можете сделать в этом месте все что захотите, например вывести сообщение в лог. На шаге 4.2 попытка соединения Wi-Fi может потерпеть неудачу, например из-за ошибки пароля, или если AP не найдена. В этом случае возникнет WIFI_EVENT_STA_DISCONNECTED, и будет предоставлена причина неудачного соединения. Для обработки событий, сигнализирующих о нарушении соединения Wi-Fi, см. описание фазы 6. 5. Wi-Fi 'Got IP' Phase s5.1: Как только клиент DHCP был инициализирован на шаге 4.2, начнется фаза получения IP-адреса (Got IP). s5.2: Если был успешно получен IP-адрес от сервера DHCP, то произойдет событие IP_EVENT_STA_GOT_IP, и event task выполнит общую обработку. s5.3: В callback-функции события приложения событие IP_EVENT_STA_GOT_IP перенаправляется в задачу приложения. Для приложений, основанных на LwIP, это событие очень специфическое, и оно означает, что все готово для того, чтобы приложение начало выполнять свои насущные операции, например создало сокет TCP/UDP. Частая ошибка - инициализация сокета перед получением события IP_EVENT_STA_GOT_IP. НЕ ЗАПУСКАЙТЕ связанные с сокетом действия до получения IP-адреса. 6. Wi-Fi Disconnect Phase s6.1: Когда соединение Wi-Fi нарушено, например из-за выключения точки доступа, или слишком низкого уровня RSSI, возникает событие WIFI_EVENT_STA_DISCONNECTED. Это событие также может произойти на фазе 3. Здесь задача событий оповестит стек LwIP о необходимости очистки/удаления всех соединений UDP/TCP. Затем все сокеты приложения получат ошибочный статус. Другими словами, ни один из сокетов не сможет правильно работать при возникновении этого события. s6.2: В сценарии, описанном выше, callback-функция события приложения перенаправит WIFI_EVENT_STA_DISCONNECTED в задачу приложения. Здесь рекомендуются действия: 1) вызывт esp_wifi_connect() для отключения Wi-Fi, 2) закрыть все сокеты, и 3) заново создать их, если это необходимо. Подробности см. в описании события WIFI_EVENT_STA_DISCONNECTED. 7. Wi-Fi IP Change Phase s7.1: Если поменялся IP-адрес, то возникнет событие IP_EVENT_STA_GOT_IP с флагом "ip_change", установленным в true. s7.2: Это важное событие для приложения. Когда оно произойдет, нужно закрыть все созданные сокеты и создать их заново. 8. Wi-Fi Deinit Phase s8.1: Вызовите esp_wifi_disconnect() для отключения Wi-Fi. s8.2: Вызовите esp_wifi_stop() для остановки драйвера Wi-Fi. s8.3: Вызовите esp_wifi_deinit() для выгрузки драйвера Wi-Fi. См. документацию [1]. Обработка событий. Обычно проще всего писать код для сценариев "удачного дня", таких как события WIFI_EVENT_STA_START и WIFI_EVENT_STA_CONNECTED. Гораздо труднее написать подпрограммы для обработки сценариев неудачи, таких как событие WIFI_EVENT_STA_DISCONNECTED. Качественная обработка плохих сценариев - фундаментальное условие для построения надежных приложений Wi-Fi. Обратитесь к врезкам "Описание событий ESP32-C3 Wi-Fi" и врезке "ESP32-C3 Wi-Fi station General Scenario". Также см. описание библиотеки цикла обработки событий [5]. WIFI_EVENT_WIFI_READY. Драйвер Wi-Fi никогда не будет генерировать это событие, так что оно может быть игнорировано в callback-функции событий приложения (application event callback). Это событие может быть удалено в последующих релизах библиотек. WIFI_EVENT_SCAN_DONE. Событие завершения сканирования срабатывает из функции esp_wifi_scan_start(), и оно возникает в следующих сценариях: · Сканирование завершено, т. е. была успешно найдена целевая точка доступа, или были просканированы все каналы. Событие scan-done не возникнет в следующих сценариях: · Это заблокированное сканирование. При получении этого события event task ничего не делает. Callback-функции события приложения нужно вызвать esp_wifi_scan_get_ap_num() и esp_wifi_scan_get_ap_records() для извлечения отсканированного списка точек доступа (AP list), и чтобы драйвер Wi-Fi освободил внутреннюю память, которая была выделена во время сканирования (не забудьте это сделать!). См. "ESP32-C3 Wi-Fi Scan" для более подробного описания. WIFI_EVENT_STA_START. Если вызов esp_wifi_start() возвратил ESP_OK, и текущий режим Wi-Fi это режим station или station/AP, то возникнет это событие. При получении этого события event task будет инициализировать сетевой интерфейс LwIP (netif). Обычно для callback-функции события приложения нужно вызвать esp_wifi_connect(), чтобы подключиться к сконфигурированной точке доступа (AP). WIFI_EVENT_STA_STOP. Если esp_wifi_stop() возвратила ESP_OK и текущий режим Wi-Fi это режим station или station/AP, то возникнет это событие. При получении этого события, event task освободит IP-адрес станции, остановит клиента DHCP, удалит связанные с TCP/UDP соединения, очистит LwIP netif станции, и т. д. Для callback-функции события приложения обычно делать ничего не надо. WIFI_EVENT_STA_CONNECTED. Если esp_wifi_connect() возвратит ESP_OK, и станция успешно подключилась к целевой точке доступа, то возникнет это событие. При получении этого события event task запустит клиента DHCP, и начнет процесс получения IP-адреса от сервера DHCP. После этого драйвер Wi-Fi готов к передаче и приему данных. Этот момент хорошо подходит для начала работы приложения при условии, что оно зависит не от LwIP, а именно от IP-адреса. Однако, если приложение основано на LwIP, то вам нужно ждать, пока не поступит событие об успешном получении IP. WIFI_EVENT_STA_DISCONNECTED. Это событие может быть сгенерировано в следующих сценариях: · Когда была вызвана esp_wifi_disconnect() или esp_wifi_stop(), и станция уже была подключена к точке доступа. При получении этого события поведение по умолчанию следующее: · Выключается LwIP netif станции. Чаще всего обработчик этого события в приложении вызывает esp_wifi_connect(), чтобы заново подключиться к Wi-Fi. Однако если это событие произошло из-за вызова esp_wifi_disconnect(), то приложение не должно вызывать esp_wifi_connect() для повторного соединения. Приложение отвечает за то, чтобы разделять ситуации, когда отключение произошло от вызова esp_wifi_disconnect(), или отключение было вызвано другими причинами. Иногда требуется более эффективная стратегия для переподключения, см. "ESP32-C3 Wi-Fi Station Connecting When Multiple APs Are Found -> Wi-Fi Reconnect" в документации [1], также далее секцию "ESP32-C3 Wi-Fi Scan -> Сканирование, когда происходит подключение Wi-Fi". Другая заслуживающая внимания вещь состоит в том, что поведение по умолчанию LwIP при получении события отключения состоит в обрыве всех соединений сокетов TCP. В большинстве случаев это не создает проблему. Однако для некоторых специальных приложений это может быть не тем, что вы хотите получить. Рассмотрим следующие сценарии: · Приложение создает соединение TCP, чтобы поддерживать на уровне приложения периодическую передачу через каждые 60 секунд данных, сигнализирующих о работоспособности устройства (keep-alive data). В этих показанных выше сценариях было бы идеальным не затрагивать сокеты приложения и сетевой уровень, поскольку соединение Wi-Fi упало только временно и очень быстро восстановилось. Приложение может разрешить "Keep TCP connections when IP changed" через LwIP menuconfig. IP_EVENT_STA_GOT_IP. Это событие возникает, когда клиент DHCP успешно получил адрес IPV4 от сервера DHCP, или когда адрес IPV4 поменялся. Событие означает, что все готово и приложение может начать выполнять свою работу (например создавать сокеты). Адрес IPV4 может поменяться по следующим причинам: · Клиент DHCP не смог выполнить обновление/привязку (renew/rebind) адреса IPV4, и IPV4 станции сбросился в 0. Поменялся адрес IPV4 или нет, показывает поле ip_change в структуре ip_event_got_ip_t. Сокет основан на адресе IPV4, это означает, что если IPV4 поменялся, то все сокеты, связанные с этим IPV4, становятся ненормальными. При получении этого события приложению нужно закрыть все сокеты и заново их создать, когда IPV4 поменялся на другой достоверный. IP_EVENT_GOT_IP6. Это событие возникает, когда поддержка IPV6 SLAAC автоматически конфигурирует адрес для ESP32-C3, или когда этот адрес изменился. Событие означает, что все готово и приложение может начать выполнять свою работу, например создать сокеты. IP_EVENT_STA_LOST_IP. Событие возникает, когда адрес IPV4 стал недопустимым. IP_EVENT_STA_LOST_IP не возникнет сразу после отключения Wi-Fi. Вместо этого запустится таймер потери адреса (IPV4 address lost timer). Если адрес IPV4 будет получен до того, как произойдет таймаут этого таймера, то событие IP_EVENT_STA_LOST_IP не произойдет. Иначе это событие произойдет, когда адрес IPV4 был потерян, и таймер потери времени истек. Обычно приложение может игнорировать это событие, потому что оно предназначено просто для отладки, чтобы информировать о потере адреса IPV4. WIFI_EVENT_AP_START. То же самое, что и WIFI_EVENT_STA_START. WIFI_EVENT_AP_STOP. То же самое, что и WIFI_EVENT_STA_STOP. WIFI_EVENT_AP_STACONNECTED. Каждый раз когда к точке доступа, реализованной на ESP32-C3, подключится станция, возникнет событие WIFI_EVENT_AP_STACONNECTED. При получении этого события event task ничего не делает, и callback-функция также может его игнорировать. Однако иногда могут понадобиться дополнительные действия, например для получения информации о подключившейся станции. WIFI_EVENT_AP_STADISCONNECTED. Это событие произойдет в следующих сценариях: · Приложение вызвало esp_wifi_disconnect() или esp_wifi_deauth_sta(), чтобы вручную отключить станцию. Когда это событие произошло, event task ничего не делает, но callback-функции события приложения нужно что-нибудь сделать, например закрыть сокет, связанный с этой станцией. WIFI_EVENT_AP_PROBEREQRECVED. Это событие по умолчанию запрещено. Приложение может разрешить его вызовом API-функции esp_wifi_set_event_mask(). Когда это событие разрешено, оно будет возникать каждый раз, когда точка доступа принимает probe request. WIFI_EVENT_STA_BEACON_TIMEOUT. Если станция не получает маяк (beacon) подключенной точки доступа во время неактивности, то происходит таймаут маяка (beacon timeout), и возникнет событие WIFI_EVENT_STA_BEACON_TIMEOUT. Приложение может установить время неактивности вызовом esp_wifi_set_inactive_time(). WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START. Возникнет в начале интервала connectionless-модуля, см. "Connectionless Modules Power-saving". Восстановление из всех ошибок. Так же, как и обработка "неудачных" сценариев, хорошо работающие подпрограммы восстановления также являются фундаментально важными для надежных приложений Wi-Fi, см. врезку "ESP32-C3 Wi-Fi API Error Code". У всех API-функций ESP32-C3 Wi-Fi имеются хорошо задокументированные значения возврата, так называемые коды ошибок (error code). Коды ошибок разделяются на категории: · Нет ошибок, например ESP_OK означает успешный возврат из API-функции. Критичность ошибки зависит от API и сценария приложения, и определяется пользователем API-функций. Основной принцип написания надежного приложения с использованием Wi-Fi API - всегда проверять код возврата, и писать код для обработки ошибок. Обычно код обработки ошибок может использоваться: · Для восстановимых ошибок, когда есть возможность написать код, который будет восстанавливать программу из состояния ошибки. Например, когда esp_wifi_start() вернет ESP_ERR_NO_MEM, может быть вызвана vTaskDelay, чтобы сделать нужную задержку перед другой попыткой. Заголовочный файл esp_err.h содержит макрос ESP_ERROR_CHECK, который проверяет коды возврата. Это довольно распространенный метод перехвата состояния ошибки, часто используемый в процессе разработки приложения. Однако настоятельно рекомендуется, чтобы пользователи реализовали свой код обработки ошибок. [Инициализация параметров ESP32-C3 Wi-Fi API] При инициализации параметров структуры для API следует придерживаться одного из двух подходов: · Явно устанавливать все поля параметров. Инициализация или извлечение корректного состояния всей структуры очень важно, поскольку в большинстве случаев значение поля 0 означает использование настройки по умолчанию. В будущем в структуру может быть добавлено больше полей, и инициализация их нулями будет гарантировать, что приложение все еще будет работать корректно после перехода на новый релиз ESP-IDF. [Модель программирования ESP32-C3 Wi-Fi] Рис. 4. Wi-Fi Programming Model. Драйвер Wi-Fi можно рассматривать как черный ящик, который ничего не знает о высокоуровневом коде, таком как стек TCP/IP, задача приложения (application task) и задача событий (event task). Задача приложения (её код) обычно вызывает API-функции драйвера Wi-Fi для инициализации Wi-Fi и по мере необходимости, когда обрабатываются события Wi-Fi. Драйвер Wi-Fi получает API-вызовы, обрабатывает их и генерирует события для приложения. Обработка событий Wi-Fi основана на библиотеке esp_event [5]. События посылаются драйвером Wi-Fi в цикл обработки событий по умолчанию (default event loop). Приложение может обработать эти события в callback-функциях, зарегистрированных вызовом esp_event_handler_register(). События Wi-Fi также обрабатываются компонентом esp_netif, чтобы обеспечить набор поведений по умолчанию. Например, когда станция Wi-Fi подключается к точке доступа (AP), esp_netif по умолчанию автоматически запустит клиента DHCP client. [ESP32-C3 Wi-Fi Scan] В настоящий момент API-функция esp_wifi_scan_start() поддерживается только в режиме станции (station mode) или в смешанном режиме (station/AP mode). Таблица 2. Типы сканирования.
Режимы сканирования, приведенные в таблице выше, могут произвольно комбинироваться, в результате получается 8 различных сканирований: · All-Channel Background Active Scan Конфигурация сканирования. Тип сканирования и другие атрибуты, относящиеся к сканированию, конфигурируются esp_wifi_scan_start(). Таблица ниже предоставляет подробное описание wifi_scan_config_t. Таблица 3. Поля конфигурации сканирования.
Также существуют некоторые глобальные атрибуты сканирования, которые конфигурируются API-функцией esp_wifi_set_config(), см. далее "Station Basic Configuration". Сканирование всех точек доступа на всех каналах (Foreground). Сценарий: Рис. 5. Foreground Scan всех каналов Wi-Fi. Сценарий, показанный выше, описывает foreground-сканирование всех каналов в текущем потоке. Foreground-сканирование может происходить только в режиме станции, когда станция не подключена ни к одной точке доступа. Какое сканирование будет происходить foreground или background - полностью определяет драйвер Wi-Fi, и это не может быть сконфигурировано приложением. Подробное описание сценария: Scan Configuration Phase s1.1: Вызов esp_wifi_set_country() для установки информации о стране (country info) если информация страны по умолчанию это то, что вам нужно. См. далее "Wi-Fi Country Code". s1.2: Вызов esp_wifi_scan_start() для конфигурации сканирования. Как это делается, см. "Конфигурация сканирования" выше. Поскольку выполняется сканирование всех каналов, то просто установите SSID/BSSID/channel в 0. Wi-Fi Driver’s Internal Scan Phase s2.1: драйвер Wi-Fi переключается на канал 1. В этом случае тип сканирования WIFI_SCAN_TYPE_ACTIVE, и probe request широковещательный (broadcasted). Иначе Wi-Fi будет ждать маяка от точки доступа. Драйвер Wi-Fi будет некоторое время (dwell time) оставаться на канале 1. Dwell time конфигурируется параметрами min/max, со значениями по умолчанию 120 мс. s2.2: Драйвер Wi-Fi переключится на канал 2, и выполнит ту же операцию, что на шаге 2.1. s2.3: Драйвер Wi-Fi сканирует последний канал N, где N определяется кодом страны, который конфигурируется на шаге 1.1. Scan-Done Event Handling Phase s3.1: Когда все каналы просканированы, возникает событие WIFI_EVENT_SCAN_DONE. s3.2: Callback-функция события приложения оповестит задачу приложения, что получено событие WIFI_EVENT_SCAN_DONE. Будет вызвана esp_wifi_scan_get_ap_num(), чтобы получить количество точек доступа, найденных во время этого сканирования. Затем выделяется достаточное количество элементов, и делается вызов esp_wifi_scan_get_ap_records() для получения записей точки доступа (AP records). Имейте в виду, что записи точки доступа в драйвере Wi-Fi будут освобождены, когда вызывается esp_wifi_scan_get_ap_records(). Не вызывайте esp_wifi_scan_get_ap_records() дважды для одного события завершения сканирования. Если esp_wifi_scan_get_ap_records() не вызвана, когда произошло событие завершения сканирования, то записи точки доступа, выделенные драйвером Wi-Fi, не будут освобождены. Поэтому убедитесь, что вызываете esp_wifi_scan_get_ap_records(), но делаете это только 1 раз. Сканирование всех точек доступа на всех каналах (Background). Сценарий: Рис. 6. Background Scan всех каналов Wi-Fi. Выше показан сценарий background-сканирования всех каналов. В отличие от foreground-сканирования всех точек доступа на всех каналах, при background-сканировании драйвер Wi-Fi будет сканировать back-to-home канал в течение 30 мс перед тем, как переключится на следующий канал, чтобы дать шанс Wi-Fi-подключению передавать/принимать данные. Сканирование определенной точки доступа на всех каналах. Сценарий: Рис. 7. Сканирование определенной AP на всех каналах Wi-Fi. Это сканирование подобно сканированию всех точек доступа на всех каналах (Foreground). Отличия следующие: s1.1: На шаге 1.2 целевая точка доступа будет сконфигурирована на SSID/BSSID. s2.1 ~ s2.N: Каждый раз, когда драйвер Wi-Fi сканирует точку доступа, происходит проверка, целевая эта точка доступа, или нет. Если сканирование WIFI_FAST_SCAN, и найдена целевая точка доступа, то возникнет событие завершения сканирования, и сканирование завершается; иначе сканирование продолжится. Обратите внимание, что первый сканируемый канал может быть не каналом 1, потому что драйвер Wi-Fi оптимизирует последовательность сканирования. Возможна ситуация, когда несколько точек доступа совпадают с информацией целевой точки доступа, например у двух точек доступа SSID установлен "ap". В этом случае, если сканирование WIFI_FAST_SCAN, то будет найдена только первая "ap". Если сканирование WIFI_ALL_CHANNEL_SCAN, то будут найдены обе "ap", и станция подключится к одной из этих "ap" в соответствии со сконфигурированной стратегией. См. далее "Station Basic Configuration". Вы можете сканировать определенную точку доступа, или все точки доступа на любом канале. Эти два сценария очень похожи. Сканирование в Wi-Fi Connect. Когда вызывается esp_wifi_connect() драйвер Wi-Fi попытается сначала сканировать сконфигурированную точку доступа. Сканирование в Wi-Fi Connect такое же, как и сканирование определенной точки доступа на всех каналах, за исключением того, что не будет сгенерировано событие завершения сканирования, когда сканирование завершено. Если найдена целевая точка доступа, то драйвер Wi-Fi начнет соединение Wi-Fi; иначе будет сгенерировано событие WIFI_EVENT_STA_DISCONNECTED. См. "Сканирование определенной точки доступа на всех каналах". Сканирование с блокировкой (Blocked Mode). Если параметр block для esp_wifi_scan_start() установлен в true, то сканирование происходит в блокирующем режиме, т. е. задача приложения будет заблокирована, пока сканирование не завершится. Сканирование с блокировкой подобно сканированию без блокировки, за исключением того, что не будет генерироваться событие завершения сканирования, когда сканирование завершилось. Параллельное сканирование. Две задачи приложения могут вызвать одновременно esp_wifi_scan_start(), или одна и та же задача приложения может вызвать esp_wifi_scan_start() до получения события завершения сканирования. Могут иметь место оба этих сценария. Однако драйвер Wi-Fi не предоставляет адекватную поддержку нескольких конкурентных сканирований. В результате следует избегать конкурентных сканирований. Поддержка конкурентного сканирования будет расширена в будущих релизах, поскольку функционал ESP32-C3 Wi-Fi постоянно улучшается. Сканирование, когда происходит подключение Wi-Fi. Вызов esp_wifi_scan_start() немедленно завершится неудачей, если происходит подключение Wi-Fi, потому что у подключения приоритет выше, чем у сканирования. Если сканирование потерпело неудачу из-за подключения, то рекомендуемая стратегия - немного подождать и попробовать произвести сканирование снова. Сканирование завершится успешно после завершения подключения. Однако стратегия retry/delay может сработать не всегда. Рассмотрим следующие сценарии: · Станция подключается к несуществующей точке доступа, или подключается к существующей, но с неправильным паролем, в таком случае всегда возникнет событие WIFI_EVENT_STA_DISCONNECTED. В показанных выше сценариях сканирование никогда не будет успешным, потому что станция находится в состоянии соединения. Так что если приложение подразумевает возможность подобного сценария, то оно должно предусмотреть лучшую стратегию повторного подключения. Например: · Приложение может выбрать определение максимальных следующих друг за другом попыток переподключения с остановкой этих попыток, когда счетчик достиг максимума. [Сценарий подключения станции Wi-Fi] Этот сценарий показывает только случай, когда на фазе сканирования найдена только одна целевая точка доступа. Для сценария, когда найдено больше одной точки доступа с одинаковыми SSID, см. "ESP32-C3 Wi-Fi Station Connecting When Multiple APs Are Found" в документации [1]. Обычно приложению не нужно заботиться о процессе подключения. Ниже приведено краткое введение в некоторые моменты процесса подключения которые могут быть интересны. Сценарий: Рис. 8. Процесс подключения станции к точке доступа Wi-Fi. Scan Phase s1.1, драйвер Wi-Fi начинает сканирование в как описано в "Wi-Fi Connect". s1.2, если сканирование прошло неудачно и целевая точка доступа не найдена, то возникнет событие WIFI_EVENT_STA_DISCONNECTED, и код причины (reason-code) будет WIFI_REASON_NO_AP_FOUND (см. далее врезку "Wi-Fi Reason Code"). Auth Phase s2.1, посылается пакет запроса аутентификации, и разрешается работа таймера аутентификации (auth-timer). s2.2, если не получен пакет ответа аутентификации до истечения таймаута таймера аутентификации, то возникнет событие WIFI_EVENT_STA_DISCONNECTED, и reason-code будет WIFI_REASON_AUTH_EXPIRE (см. далее врезку "Wi-Fi Reason Code"). s2.3, Получен пакет ответа на запрос аутентификации (auth-response), и auth-timer останавливается. s2.4, точка доступа отклонила аутентификацию в ответе, возникнет событие WIFI_EVENT_STA_DISCONNECTED, и reason-code будет WIFI_REASON_AUTH_FAIL, или причины отказа будут указаны точкой доступа (см. далее врезку "Wi-Fi Reason Code"). Association Phase s3.1, посылается запрос ассоциации (association request), и разрешается работа таймера ожидания ассоциации. s3.2, если ответ на запрос ассоциации не получен до истечения таймаута таймера ожидания ассоциации, то возникнет событие WIFI_EVENT_STA_DISCONNECTED, и reason-code будет WIFI_REASON_ASSOC_EXPIRE (см. далее врезку "Wi-Fi Reason Code"). s3.3, получен ответ на запрос (association response), и таймер ожидания ассоциации останавливается. s3.4, точка доступа отклонила ассоциацию в ответе, возникнет событие WIFI_EVENT_STA_DISCONNECTED, и reason-code указывается в ответе на запрос ассоциации (см. далее врезку "Wi-Fi Reason Code"). Four-way Handshake Phase s4.1, разрешается handshake-таймер, 1/4 EAPOL не получен до истечения таймаута handshake-таймера, возникнет событие WIFI_EVENT_STA_DISCONNECTED, и reason-code будет WIFI_REASON_HANDSHAKE_TIMEOUT (см. далее врезку "Wi-Fi Reason Code"). s4.2, получен 1/4 EAPOL. s4.3, станция (STA) ответила 2/4 EAPOL. s4.4, если 3/4 EAPOL не получен до истечения таймаута handshake-таймера, возникнет событие WIFI_EVENT_STA_DISCONNECTED, и reason-code будет WIFI_REASON_HANDSHAKE_TIMEOUT (см. далее врезку "Wi-Fi Reason Code"). s4.5, получен 3/4 EAPOL. s4.6, STA ответила 4/4 EAPOL. s4.7, STA генерирует событие WIFI_EVENT_STA_CONNECTED. Таблица ниже показывает значения reason-code (коды причины), определенные в библиотеке ESP32-C3. Первый столбец это имя макроса, определенное в esp_wifi_types.h. Общий префикс WIFI_REASON из имен был удален, т. е. UNSPECIFIED в реальности соответствует WIFI_REASON_UNSPECIFIED, и так далее. Второй столбец это значение причины. Третий столбец это стандартное значение, которое отображается как reason (причина) в секции 8.4.1.7 стандарта IEEE 802.11-2012 (для дополнительной информации см. этот стандарт). Последний столбец описывает reason. Таблица 4. Reason-коды.
[Конфигурация ESP32-C3 Wi-Fi] Когда разрешено Wi-Fi NVS, вся конфигурация сохраняется во flash, иначе см. Wi-Fi NVS Flash. Wi-Fi Mode. Вызовите esp_wifi_set_mode(), чтобы установить режим Wi-Fi. Таблица 5. Константы режима Wi-Fi.
Station Basic Configuration. API-функция esp_wifi_set_config() может использоваться для конфигурирования режима станции. Следующая таблица более подробно описывает поля конфигурации. Таблица 6. Поля конфигурации.
Внимание: режимы безопасности WEP/WPA устарели в спецификациях IEEE 802.11-2016, и их использование не рекомендуется. Эти режимы могут быть отклонены с использованием порога режима аутентификации (authmode threshold) путем установки threshold как WPA2 через threshold.authmode в WIFI_AUTH_WPA2_PSK. AP Basic Configuration. См. документацию [1]. Wi-Fi Protocol Mode. В настоящее время ESP-IDF поддерживате следующие режимы протокола. Таблица 7. Режимы протокола Wi-Fi.
Режим Long Range (LR) это патентованный компанией Espressif режим Wi-Fi, который может работать на расстоянии до 1 километра в прямой видимости. У него чувствительность приема лучше, он устойчивее к помехам, и больше расстояние для передачи по сравнению с традиционным режимом 802.11B. LR-совместимость. Поскольку LR это уникальный режим Wi-Fi от Espressif, и только устройства ESP32-C3 могут передавать и принимать данные LR. Другими словами, устройство ESP32-C3 НЕ ДОЛЖНО передавать данные в режиме скорости LR (LR data rate), если подключенное устройство не поддерживает LR. Приложение может достичь этого конфигурированием подходящего режима Wi-Fi. Если при согласовании режимов выясняется поддержка режима LR, то ESP32-C3 может передавать данные LR rate, иначе ESP32-C3 будет передавать все данные традиционным Wi-Fi data rate. Следующая таблица показывает процесс согласования режимов (Wi-Fi mode negotiation). Таблица 8. Согласование режимов.
В этой таблице строка соответствует режиму Wi-Fi точки доступа (AP), и столбец это режим станции Wi-Fi. Символ "-" показывает, что режимы Wi-Fi точки доступа и станции несовместимы. По этой таблице можно сделать следующие выводы: · Для разрешенного LR в точке доступа на основе ESP32-C3 получается несовместимость с традиционным режимом 802.11, потому что beacon посылается в режиме LR. Если согласованный режим Wi-Fi поддерживает и традициональный режим 802.11, и режим LR, то в области ответственности драйвера Wi-Fi остается автоматический выбор самой лучшей скорости (data rate) в разных режимах Wi-Fi, и приложению об этом заботиться не нужно. Влияние LR на традиционное устросйтво Wi-Fi. Передача данных в LR rate не влияет на традиционное устройство Wi-Fi по следующим причинам: · Процесс CCA и backoff в режиме LR соответствует спецификации 802.11. Другими словами, impact transmission в режиме LR подобно тому, как происходит impact в режиме 802.11B. Расстояние передачи LR. Чувствительность приема LR на 4 dB выше, чем у традиционного режима 802.11B, что теоретически дает выигрыш в дальности связи от 2 до 2.5 раз по сравнению с расстоянием 11B. Пропускная способность LR. У LR rate очень ограниченная пропускная способность, потому что скорость сырых данных на физическом уровне (raw PHY data rate) режима LR составляет 1/2 Mbits и 1/4 Mbits. Когда лучше использовать LR. Общие условия для использования LR: · На обоих сторонах обмена (точка доступа и станция) доступен режим LR. Вызовите esp_wifi_set_country() для установки информации страны (country info). В следующей таблице описываются подробно поля конифгурации, для установки этих полей см. описание локальных регуляторных ограничений для 2.4 GHz RF. Таблица 9. Поля конфигурации информации страны.
Country info по умолчанию {.cc=”CN”, .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO}, если режим Wi-Fi установлен для сосуществования станции и точки доступа (station/AP coexist mode), то они используют одинаковую сконфигурированную country info. Иногда country info точки доступа, к которой подключается станция, отличается от сконфигурированной country info. Например, у сконфигурированной станции country info {.cc=”JP”, .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO}, но у подключенной точки доступа country info {.cc=”CN”, .schan=1, .nchan=13}, тогда используется country info подключенной точки доступа. Следующая таблица показывает country info, используемую в разных режимах Wi-Fi и разных политиках страны, также описано влияние на активное сканирование. Таблица 10. Влияние параметров на активное сканирование.
Home Channel. В режиме точки доступа домашний канал (home channel) определяется как канал точки доступа (AP channel). В режиме точки доступа домашний канал определяется как канал точки доступа, на котором станция подключена. В режиме сосущетвования Station/AP домашний канал точки доступа и домашний канал станции должны быть одинаковыми, а если они отличаются, то домашний канал станции всегда имеет приоритет. Расмотрим пример: канал 6 точки доступа, и станция подключилась к точке доступа на канале 9. Поскольку у домашнего канала станции приоритет выше, то точка доступа должна переключится со своего канала 6, чтобы гарантировать, чтобы у станции был такой же домашний канал. При переключении канала ESP32-C3 в режиме SoftAP будет оповещать подключенные станции о миграции канала, используя Channel Switch Announcement (CSA). Станции, которые поддерживают переключение канала, перейдут на новый канал без отключения и переподключения к SoftAP. По умолчанию все управление кадрами (Wi-Fi management frames) осуществляет драйвер Wi-Fi, и приложению об этом заботиться не нужно. Однако некоторые приложения могут обрабатывать кадры beacon, probe request, probe response и другие кадры управления. Например, если вы вставите что-то специфичное для вендора IE в кадры управления, то будут обработаны только те кадры управления, которые содержат это vendor-specific IE. В ESP32-C3, esp_wifi_set_vendor_ie() и esp_wifi_set_vendor_ie_cb() отвечают за этот вид функционала. [Wi-Fi Easy Connect™ (DPP)] Технология Wi-Fi Easy ConnectTM (или Device Provisioning Protocol) это безопасный и стандартизированный протокол для конфигурирования устройств Wi-Fi. Дополнительную информацию можно найти в описании API esp_dpp [6]. WPA2-Enterprise. Это безопасный механизм аутентификации для корпоративных беспроводных сетей (enterprise wireless networks). Механизм использует сервер RADIUS для аутентификации пользователей сети перед подключением их к точке доступа (Access Point, AP). Процесс аутентификации основан на политике 802.1X, и поставляется вместе с разными методами расширенного протокола аутентификации (Extended Authentication Protocol, EAP) наподобие TLS, TTLS, PEAP и т. п. Сервер RADIUS аутентифицирует пользователей на основе их учетных записей (username и password), цифровых сертификатов, или с помощью обоих этих средств. Когда ESP32-C3 в режиме станции пытается подключиться к точке доступа в режиме Enterprise, она посылает запрос аутентификации (authentication request) точке доступа, которая в свою очередь пересылает запрос серверу RADIUS, чтобы аутентифицировать станцию. На основе различных методов EAP, могут быть установлены параметры конфигурации с помощью idf.py menuconfig. WPA2_Enterprise поддерживается ESP32-C3 только в режиме станции (Station mode). Для установки безопасного соединения точка доступа и станция договариваются и приходят к соглашению по самому лучшему возможному для использования шифровальщику. ESP32-C3 поддерживает метод 802.1X/EAP (WPA) стандарта AKM and Advanced encryption с протоколом шифрования Counter Mode Cipher Block Chaining Message Authentication (AES-CCM). Также возможна поддержка шифровальщиков, которые допустимы библиотекой mbedtls, если установлен флаг USE_MBEDTLS_CRYPTO. ESP32-C3 в настоящий момент поддерживает следующие методы EAP: EAP-TLS: метод, основанный на сертификате, и он требует только SSID и EAP-IDF. PEAP: метод Protected EAP. Обязательно использование Username и Password. EAP-TTLS: метод, основанный на учетных записях. Обязательна только аутентификация сервера, аутентификация пользователя опциональна. Username и Password обязательны. Поддерживаются разные методы Phase2, наподобие: - PAP: Password Authentication Protocol. Подробную информацию о создании сертификатов, и как запустить пример wpa2_enterprise на ESP32-C3, см. репозиторий wifi/wifi_enterprise [7]. [Wireless Network Management] Wireless Network Management позволяет клиентским устройствам обмениваться информацией о топологии сети, включая информацию, связанную с условиями распространения радиосигнала (RF environment). Это делает каждого клиента лучше осведомленным о сети, повышая общую производительность беспроводной сети. Это часть спецификации 802.11v. Также это позволяет клиенту поддерживать Network assisted Roaming. Network assisted Roaming позволяет WLAN посылать сообщения соответствующим клиентам, в результате клиенты связываются с точками доступа, у которых лучшие метрики для связи. Это полезно как для балансировки нагрузки беспроводной сети, так и направлению подключения для клиентов, испытывающих проблемы со связью. Текущая реализация 802.11v включает поддержку для кадров управления быстрым роумингом (BSS transition management frames). [Radio Resource Measurement] Стандарт управления ресурсами радиоканала (Radio Resource Measurement, 802.11k) предназначен для улучшения распространения трафика по сети. В беспроводной сети (wireless LAN, WLAN) каждое устройство обычно подключается к той точке доступа (access point, AP), от которой приходит более сильный сигнал. В зависимости от количества конкурирующих подписчиков и их географического места расположения такое согласование общего радиоканала может привести к чрезмерной нагрузке на одну точку доступа, и недостаточное использование других точек доступа, в результате производительность сети ухудшается. В организации сети, удовлетворяющей стандарту 802.11k, если у точки доступа самый сильный сигнал, и она загружена полностью, то беспроводное устройство может быть перемещено на одну из других недогруженных точек доступа. Даже если уровень сигнала может быть ниже, общая пропускная способность при этом повысится за счет более эффективного использования сетевых ресурсов. Текущая реализация 802.11k включает поддержку отчета измерения маяка (beacon measurement report), отчета измерения линка (link measurement report) и опроса соседа по сети (neighbor request). См. описание примера ESP-IDF examples/wifi/roaming/README.md для настройки и использования этих API-функций. Код примера только демонстрирует, как использовать этот функционал, и приложение должно определить собственный алгоритм для разных случаев использования. [Wi-Fi Location] Wi-Fi Location улучшает точность данных месторасположения (location data) по отношению к точке доступа (Access Point, AP), что позволяет создавать новые, богатые возможностями приложения и службы, такие как геозонирование (geo-fencing), управление сетью (network management), навигация и другие полезные функции. Один из протоколов, который используется для определения места положения устройства по отношению к точке доступа - Fine Timing Measurement, который вычисляет время доставки по радио (Time-of-Flight) кадра Wi-Fi. Fine Timing Measurement (FTM). FTM используется для измерения круговой задержки распространения сигнала Wi-Fi Round Trip Time (Wi-Fi RTT), что дает возможность измерить время, за которое сигнал проходит от одного устройства к другому, и обратно. С помощью Wi-Fi RTT расстояние между устройствами может быть вычислено по простой формуле RTT * c / 2, где c это скорость света. FTM использует метки времени, предоставляемые аппаратурой интерфейса Wi-Fi в моменты, когда кадры Wi-Fi приходят или уходят при обмене между парами устройств. Один из участников такого измерения, который называется FTM Initiator (обычно это устройство станции), обнаруживает другой объект, FTM Responder (может быть либо станцией, либо точкой доступа), и согласовывает запуск процедуры FTM. Эта процедура использует несколько кадров Action, отправляемых пачками, и подтверждений на них (ACK-кадры), чтобы определить по меткам времени задержку. FTM Initiator захватывает данные в конце этого процесса, и вычисляет среднее Round-Trip-Time. ESP32-C3 поддерживает технологию FTM в следующей конфигурации: · ESP32-C3 как FTM Initiator в режиме станции. Измерение дистанции с использованием RTT неточное, потому что на измерение влияют такие факторы, как наложение и отражение сигналов RF, множественные пути распространения сигнала, ориентация антенны и неточность калибровки. Чтобы улучшить результаты, рекомендуется выполнить FTM между двумя устройствами ESP32-C3, работающими как станция и SoftAP. См. ESP-IDF файл описания примера examples/wifi/ftm/README.md для необходимых шагов по настройке и выполнению FTM. [ESP32-C3 Wi-Fi Power-saving Mode] Station Sleep (режим сна станции). В настоящий момент ESP32-C3 Wi-Fi поддерживает режим Modem-sleep, который относиться к обычному режиму пониженного энергопотреблению (power-saving mode) в протоколе IEEE 802.11. Режим Modem-sleep работает в режиме "только станция" (Station-only mode) и станция сначала должна подключиться к точке доступа (AP). Если разрешен режим Modem-sleep, то станция будет периодически переключаться между состоянием активности (active) и сна (sleep). В состоянии сна блоки RF, PHY и BB выключаются для снижения энергопотребления. В режиме modem-sleep станция может сохранять соединение с точкой доступа. Режим Modem-sleep включает режимы минимального снижения потребления мощности (minimum power save mode) и максимального снижения потребления мощности (maximum power save mode). В minimum power save mode, станция пробуждается каждый DTIM для приема маяка (beacon). Данные широковещания (broadcast data) не теряются, потому что передаются после DTIM. Однако если DTIM короткий, то не получается экономить значительное количество мощности, и DTIM определяется точкой доступа. В maximum power save mode станция пробуждается в каждом интервале прослушивания для приема маяка. Этот интервал прослушивания (listen interval) может быть установлен больше, чем период DTIM точки доступа. В этом случае данные широковещания могут быть потеряны, потому что станция может быть в состоянии сна во время DTIM. Чем интервал прослушивания дольше, тем больше мощности экономится, однако больше теряется данных широковещания. Интервал прослушивания может быть сконфигурирован вызовом esp_wifi_set_config() перед подключением к точке доступа. Вызовите esp_wifi_set_ps(WIFI_PS_MIN_MODEM) для разрешения режима минимального сохранения энергии Modem-sleep, или esp_wifi_set_ps(WIFI_PS_MAX_MODEM) для режима максимального сохранения энергии после вызова esp_wifi_init(). Когда станция подключилась к точке доступа, запуститься режим Modem-sleep. Когда станция отключится от точки доступа, режим Modem-sleep остановится. Вызовите esp_wifi_set_ps(WIFI_PS_NONE) для полного запрета modem sleep. Это приведет к намного большему потреблению энергии, однако предоставит минимальную латентность для приема данных Wi-Fi в реальном времени. Когда режим modem sleep разрешен, принятые данные Wi-Fi могут задерживаться пока длится период DTIM (в режиме минимального сохранения энергии), или интервал прослушивания (в режиме максимального сохранения энергии). Полный запрет modem sleep невозможен для совместного использования Wi-Fi и Bluetooth. Режим по умолчанию Modem-sleep - WIFI_PS_MIN_MODEM. AP Sleep (режим сна точки доступа). В настоящее время точка доступа на основе ESP32-C3 не поддерживает все возможности экономии энергии, определенные в спецификации Wi-Fi. Если точнее, то точка доступа только кэширует unicast-данные для станций, подключенных к этой точке доступа, но multicast-данные для станций не кэшируются. Если на станциях, подключенных к точке доступа на ESP32-C3, разрешен режим пониженного потребления энергии, то может быть потеря multicast-пакетов. В будущем планируется реализовать поддержку всех функций энергосбережения на точке доступа ESP32-C3. Connectionless Modules Power-saving. Модули без подключения (сonnectionless modules) это модули Wi-Fi, которые не зависят от подключения Wi-Fi, например ESP-NOW, DPP, FTM. Эти модули запускаются из esp_wifi_start(), и работают до esp_wifi_stop(). В настоящий момент, если ESP-NOW работает в режиме станции, то поддерживается sleep как в состоянии connected, так и в состоянии disconnected. Connectionless Modules TX. Для каждого connectionless-модуля поддерживается TX в любое время сна без какой-либо дополнительной конфигурации. Между тем esp_wifi_80211_tx() также поддерживается в режиме sleep. Connectionless Modules RX. Для каждого connectionless-модуля должны быть сконфигурированы 2 параметра для RX в режиме sleep: Window и Interval. В начале времени интервала (Interval) блоки RF, PHY, BB должны быть включены и удерживаться на время Window. Connectionless Module может принимать (RX) в течение этого времени. Interval · Существует только один Interval. Он конфигурируется вызовом esp_wifi_set_connectionless_interval(), указывается значение в миллисекундах. Window · У каждого connectionless-модуля после запуска есть свое собственное окно (Window). Connectionless Modules Power-saving будут работать с самым максимальным из них. Использование окна RF, PHY и BB в разных условиях
Режим по умолчанию. Если Interval равен ESP_WIFI_CONNECTIONLESS_INTERVAL_DEFAULT_MODE с ненулевым Window, то Connectionless Modules Power-saving будут работать в режиме по умолчанию. В этом режиме RF, PHY, BB будут удерживаться включенными, если не будет сосуществования (no coexistence) с протоколом, отличающимся от Wi-Fi. При сосуществовании (coexistence) ресурсы RF, PHY, BB выделяются coexistence-модулем для модуля Wi-Fi connectionless и модуля non-Wi-Fi с использованием метода разделения времени. В режиме по умолчанию модулю Wi-Fi connectionless разрешено периодически использовать RF, BB, PHY при стабильной производительности. Рекомендуется конфигурировать Connectionless Modules Power-saving в режим по умолчанию, если модуль Wi-Fi connectionless работает вместе с модулем non-Wi-Fi. [Пропускная способность радиоканала ESP32-C3 Wi-Fi] В следующей таблице показаны самые лучшие результаты по пропускной способности, полученные при лабораторных испытаниях для модуля, заключенного в экран. Таблица 11. Пропускная способность в разных условиях использования.
Когда пропускная способность тестируется с помощью примера iperf, используется sdkconfig в файле examples/wifi/iperf/sdkconfig.defaults.esp32c3. [Отправка пакета Wi-Fi 80211] API-функция esp_wifi_80211_tx() может использоваться для следующих целей: · Отправка маяка (beacon), probe request, probe response, action frame. Это не может использоваться для отправки шифрованых кадров или кадров с QoS. Предварительные условия для использования esp_wifi_80211_tx(): · Режим Wi-Fi или Station, или AP, или Station+AP. Скорость передачи данных. Если соединение Wi-Fi отсутствует, скорость передачи данных составляет 1 Мбит/с. При наличии Wi-Fi-соединения и наличии пакета от станции к точке доступа или от точки доступа к станции скорость передачи данных совпадает со скоростью передачи данных по Wi-Fi-соединению. В противном случае скорость передачи данных составляет 1 Мбит/с. Побочные эффекты, которых надо избегать в различных сценариях. Теоретически, если мы не рассматриваем побочные эффекты, которые API накладывает на драйвер Wi-Fi или другие станции/точки доступа, мы можем послать по радио необработанный пакет 802.11, с любым MAC назначения, любым MAC источника, любым BSSID или любым другим типом пакета. Однако надежные/полезные приложения должны избегать таких побочных эффектов. В таблице ниже приведены некоторые советы/рекомендации, как избежать побочных эффектов esp_wifi_80211_tx () в различных сценариях. Таблица 12. Советы по надежному использованию.
[Wi-Fi Sniffer Mode] Режим снифера Wi-Fi можно разрешить вызовом esp_wifi_set_promiscuous(). Если режим снифера разрешен, то приложение может выводить дампы следующих пакетов: · 802.11 Management frame. Дамп следующих пакетов не может быть выведен приложением: · 802.11 error frame, такой как кадо с ошибкой CRC, и т. п. Для кадров, которые сниффер может вывести в дамп, приложение может дополнительно определить, какой определенный тип пакетов можно отфильтровать, используя esp_wifi_set_promiscuous_filter() и esp_wifi_set_promiscuous_ctrl_filter(). По умолчанию для приложения фильтруются все кадры данных (802.11 data frames) и кадры управления (management frames). Сниффер Wi-Fi может быть разрешен в режиме WIFI_MODE_NULL, WIFI_MODE_STA, WIFI_MODE_AP или WIFI_MODE_APSTA. Другими словами, режим снифера активен, когда станция подключена к AP, или когда у AP есть соединение Wi-Fi. Обратите внимание, что сниффер сильно ухудшает пропускную способность Wi-Fi соединения станции или Wi-Fi соединения точки доступа. Обычно мы не должны разрешать сниффер, когда Wi-Fi соединение станции/AP передает плотный трафик, если на то нет веских причин. Есть еще одна проблема, связанная со сниффером - callback-функция wifi_promiscuous_cb_t. Этот callback будет вызываться непосредственно из задачи драйвера (Wi-Fi driver task), так что если у приложения есть какая-либо обработка для каждого отфильтрованного пакета, то рекомендуется в этом callback публиковать событие (post event) в задачу приложения (application task), чтобы переложить реальную обработку не на драйвер, а на код приложения, выполняющийся в фоновом режиме. Выбор нескольких антенн Wi-Fi показан на следующей картинке: Рис. 9. Подключение нескольких антенн к ESP32-C3. ESP32-C3 поддерживает до 16 антенн, подключенных через внешний коммутатор. Антенный коммутатор может управляться четырьмя выводами адреса - antenna_select[0:3]. Различные значения antenna_select[0:3] выберут определенную антенну. Например, значение 0b1011 означает, что коммутатор выберет антенну 11. Значение по умолчанию antenna_select[3:0] равно 0b0000, т. е. выбрана антенна 0. Для вывода адреса антенны используется до 4 портов GPIO. ESP32-C3 может выбрать антенну путем управления портами GPIO[0:3]. API-функция esp_wifi_set_ant_gpio() используется для конфигурирования, какие порты GPIO подключены к antenna_select. Если GPIO[x] соединен с antenna_select[x], то gpio_config->gpio_cfg[x].gpio_select должен быть установлен в 1, и должен быть предоставлен gpio_config->gpio_cfg[x].gpio_num. Хотя поддерживается до 16 антенн, только одна или две антенны могут быть разрешены одновременно для RX/TX. API-функция esp_wifi_set_ant() используется для конфигурирования, какая из антенн разрешена. Алгоритм разрешенных антенн также конфигурируется esp_wifi_set_ant(). Режим антенны RX/TX может быть WIFI_ANT_MODE_ANT0, WIFI_ANT_MODE_ANT1 или WIFI_ANT_MODE_AUTO. Если режим антенны WIFI_ANT_MODE_ANT0, то разрешена антенна 0 для приема и передачи данных (RX/TX data). Если режим антенны WIFI_ANT_MODE_ANT1, то для RX/TX data разрешена антенна 1. Иначе Wi-Fi автоматически выберет антенну, у которой лучший сигнал из всех разрешенных антенн. Если режим RX антенны WIFI_ANT_MODE_AUTO, то нужно также установить режим антенны по умолчанию. Из-за того, что переключение антенны RX произойдет только при удовлетворении некоторых условий, например RX антенна начитает переключение, если RSSI меньше -65 dBm, и если у другой антенны сигнал лучше, и RX использует антенную по умолчанию, если это условие не выполняется. Если режим антенны по умолчанию WIFI_ANT_MODE_ANT1, то разрешенная антенна 1 используется как RX антенна по умолчанию, иначе разрешенная антенна 0 используется как RX антенна по умолчанию. Следует учитывать некоторые ограничения: · Антенна TX может быть установлена в WIFI_ANT_MODE_AUTO только если режим RX антенны WIFI_ANT_MODE_AUTO, потому что алгоритм выбора антенны TX основан на антенне RX при WIFI_ANT_MODE_AUTO. Для использования нескольких антенн рекомендуются следующие сценарии: · В Wi-Fi режиме WIFI_MODE_STA оба режима RX/TX антенны конфигурируются в WIFI_ANT_MODE_AUTO. Драйвер Wi-Fi автоматически выберет лучшую из RX/TX антенн. Конфигурация с несколькими антеннами Wi-Fi. Для конфигурирования нескольких антенн обычно выполняют следующие шаги: 1. Конфигурируются порты GPIO, которые используются для адреса антенны antenna_selects. Например, если поддерживаются 4 антенны, и GPIO20/GPIO21 подключены к коммутатору антенны (antenna_select[0]/antenna_select[1]), то конфигурация может выглядеть следующим образом: wifi_ant_gpio_config_t config = { { .gpio_select = 1, .gpio_num = 20 }, { .gpio_select = 1, .gpio_num = 21 } }; 2. Конфигурируется, какие антенны разрешены, и как RX/TX используют разрешенные антенны. Например, если разрешены antenna1 и antenna3, то RX нужно выбрать лучшую антенну автоматически, и использовать antenna1 как антенну по умолчанию, то TX всегда выберет antenna3. Конфигурация может выглядеть примерно так: wifi_ant_config_t config = { .rx_ant_mode = WIFI_ANT_MODE_AUTO, .rx_ant_default = WIFI_ANT_ANT0, .tx_ant_mode = WIFI_ANT_MODE_ANT1, .enabled_ant0 = 1, .enabled_ant1 = 3 }; [Wi-Fi Channel State Information] Информация о состоянии канала (CSI) относится к соединению Wi-Fi. В ESP32-C3 эта информация состоит из частотных откликов каналов поднесущих и оценивается при приеме пакетов от передатчика. Каждый частотный отклик канала поднесущей записывается комплексным значением в виде двух байт со знаком. Первый обозначает мнимую (imaginary) часть, и второй реальную (real) часть. Существует до трех полей частотных откликов канала в зависимости от типа принятого пакета. Это пакеты LLTF, HT-LTF и STBC-HT-LTF. Для различных типов пакетов, которые приняты на каналах с различным состоянием в следующей таблице показаны индекс поднесущей (sub-carrier index) и байты комплексных значений CSI. Таблица 13. Состояния канала, индекс поднесущей, байты CSI.
Вся информация из этой таблицы находится в структуре wifi_csi_info_t. · Вторичный канал относится к полю secondary_channel поля rx_ctrl. Примечания: · Для пакета STBC предоставляется CSI для каждого продолжительного потока без CSD (Cyclic Shift Delay [13]). Поскольку каждый циклический сдвиг на дополнительных цепях должен быть -200 нс, в поднесущей 0 (sub-carrier) HT-LTF и STBC-HT-LTF записывается только угол CSD первого пространственно-временного потока для отсутствия частотной характеристики канала в поднесущей 0. CSD[10:0] кодируется 11 битами, в диапазоне от -pi до pi. [Конфигурирование Wi-Fi Channel State Information] Для использования Wi-Fi CSI нужно выполнить следующие шаги. · Выберите Wi-Fi CSI в menuconfig, это находится в разделе Components config –> Wi-Fi –> WiFi CSI(Channel State Information). Callback-функция приема CSI запускается из задачи драйвера Wi-Fi (Wi-Fi task). Таким образом, в этой callback-функции не должно быть долгих операций. Вместо этого поместите необходимые данные в очередь, и обрабатывайте их в задаче с более низким приоритетом. Из-за того, что станция не принимает любой пакет, когда она отключена, и принимает только пакеты от точки доступа, когда станция подключена, рекомендуется разрешит режим sniffer, чтобы принимать больше CSI data путем вызова esp_wifi_set_promiscuous(). [Wi-Fi HT20/HT40] ESP32-C3 поддерживает полосу частот Wi-Fi HT20 или HT40, но не одновременно. Может использоваться вызов esp_wifi_set_bandwidth(), чтобы поменять полосу по умолчания станции или точки доступа. HT40 является полосой по умолчанию для станции или точки доступа на основе ESP32-C3. В режиме станции фактическая полоса пропускания сначала согласовывается по время Wi-Fi подключения. И это полоса HT40 только если обе стороны - станция и точка доступа - её поддерживают, иначе используется HT20. Если меняется полоса подключенной точки доступа, то фактическая полоса пропускания согласовывается заново без отключения Wi-Fi. Подобным образом в режиме точки доступа фактическая полоса пропускания согласовывается между точкой доступа (AP) и станциями, которые к ней коннектятся. Выбирается HT40, если обе стороны соединения это поддерживают, иначе выбирается HT20. В режиме совмещения стация/точка доступа (station/AP coexist mode), устройство может сконфигурировать HT20/40 по отдельности. Если и станция, и точка доступа обе договорились о HT40, то канал HT40 должен быть каналом станции, потому что на ESP32-C3 у станции всегда более высокий приоритет, чем у точки доступа. Например, сконфигурированная полоса частот у точки доступа HT40, сконфигурированный primary-канал 6 и сконфигурированный secondary-канал 10. Станция подключена к роутеру, у которого primary-канал 6 и secondary-канал 2, то фактический канал точки доступа автоматически меняется на primary 6 и secondary 2. Теоретически у HT40 может быть лучше пропускная способность, потому что максимальная физическая скорость данных на низком уровне (PHY) для HT40 150 Mbps, в то время как у HT20 72Mbps. Однако если устройство работает в некотором специальном окружении, например слишком много других Wi-Fi устройств вокруг устройства ESP32-C3, то производительность HT40 может ухудшиться. Таким образом, если приложениям надо поддерживать такой же или подобные сценарии, то рекомендуется всегда конфигурировать полосу частот HT20. [Wi-Fi QoS] ESP32-C3 поддерживает все обязательные функции, требуемые сертификацией WFA Wi-Fi QoS. Спецификацией Wi-Fi определены 4 категории качества доступа AC (Access Category), у каждой AC назначен свой приоритет для доступа к каналу Wi-Fi. Дополнительно определяется правило привязки (map rule), которое связывает приоритет QoS другого протокола, такого как 802.11D и TCP/IP precedence, с Wi-Fi AC. В следующей таблице описывается, как IP Precedences привязываются к категориям Wi-Fi AC на устройстве ESP32-C3. Также определяется, поддерживается ли AMPDU для AC. Таблица сортируется в порядке убывания приоритета, т.е. AC_VO имеет наивысший приоритет. Таблица 14. Приоритеты трафика Wi-Fi.
Приложение может использовать фичу QoS конфигурированием IP precedence через socket-опцию IP_TOS. Пример, как создать сокет для использования очереди VI: const int ip_precedence_vi = 4; const int ip_precedence_offset = 5; int priority = (ip_precedence_vi « ip_precedence_offset); setsockopt(socket_id, IPPROTO_IP, IP_TOS, &priority, sizeof(priority)); Теоретически AC с более высоким приоритетом имеет производительность лучше, чем AC с приоритетом ниже, однако это не всегда верно. Несколько рекомендаций о том, как использовать Wi-Fi QoS: · Для некоторого особо важного трафика приложения его можно поместить в очередь AC_VO. Избегайте посылать большой трафик через очередь AC_VO. С одной стороны, очередь AC_VO не поддерживает AMPDU и не может получить лучшую производительность, чем другая очередь, если трафик слишком плотный, с другой стороны это может влиять на кадры управления (management frames), которые также используют очередь AC_VO. [Wi-Fi AMSDU] ESP32-C3 поддерживает AMSDU приема и передачи. [Wi-Fi Fragment] ESP32-C3 поддерживает прием и передачу фрагмента Wi-Fi. [WPS Enrollee] ESP32-C3 поддерживает фичу WPS enrollee в режимах WIFI_MODE_STA или WIFI_MODE_APSTA. В настоящий момент поддерживается WPS enrollee типа PBC и PIN. [Wi-Fi Buffer Usage] В этой секции описывается только конфигурирование динамических буферов. Почему конфигурирование буфера так важно. Чтобы получить по настоящему высокопроизводительную систему, следует уделить особое внимание использованию и конфигурированию памяти по следующим причинам: · Доступная память ESP32-C3 весьма ограничена. По этим причинам лучше всего рассматривать специально разрабатывать конфигурацию памяти для каждого отдельного приложения. Динамический буфер против статического. Как уже упоминалось, по умолчанию драйверы Wi-Fi используют динамические буферы (память кучи). Во многих случаях динамическое выделение памяти позволяет значительно экономить оперативную память. Однако это несколько усложняет написание приложения, потому что в этом случае приложению нужно учитывать, что память кучи также используется и для Wi-Fi. Стек lwIP также выделяет буферы на слое TCP/IP, и эти буферы также динамические. См. секцию "Performance Optimization" документации lwIP [14], где описывается использование памяти и производительность этой библиотеки. Пиковое использование динамического буфера Wi-Fi. Драйвер Wi-Fi поддерживает несколько типов буфера (см. далее "Конфигурирование буфера Wi-Fi"). Однако в этой секции акцент описания сосредоточен только на динамическом буфере Wi-Fi. Пиковый расход кучи, на выделение памяти для Wi-Fi имеет теоретический максимум, который драйвер Wi-Fi может потребить. Обычно пиковый расход памяти зависит от следующего: · Сконфигурированное количество динамических буферов приема: wifi_rx_dynamic_buf_num. Таким образом, пиковое количество памяти кучи, которое может потребить драйвер Wi-Fi, можно вычислить по следующей формуле: wifi_dynamic_peek_memory = (wifi_rx_dynamic_buf_num * wifi_rx_pkt_size_max) Как правило можно не заботится о динамических буферах под пакеты кадров управления, потому что они оказывают незначительное влияние на систему. [Как повысить производительность Wi-Fi] На производительность ESP32-C3 Wi-Fi влияет множество параметров, и между каждым из параметров существуют взаимозависимые ограничения. Правильно подобранная конфигурация может не только улучшить производительность, то также повысить количество доступной памяти для приложений и улучшить стабильность работы. В этой секции мы кратко рассмотрим рабочий режим стека протоколов Wi-Fi/LWIP и объясним роль каждого параметра. Будут даны примеры нескольких рекомендуемых рангов конфигураций, пользователь может выбрать подходящий вариант в соответствии со своим сценарием использования. Рабочий режим стека протоколов Рис. 10. Путь прохождения данных ESP32-C3. Стек протокола ESP32-C3 поделен на 4 слоя: Application (приложение), LWIP (поддержка TCP/IP, UDP, ICMP), Wi-Fi и Hardware (аппаратный уровень). · Во время приема аппаратура помещает принятый пакет в буфер DMA, и затем передает его в RX-буфер Wi-Fi, после чего в LWIP для обработки соответствующего протокола, и далее на уровень приложения. Буфер Wi-Fi RX и буфер LWIP RX по умолчанию используют одну и ту же память. Другими словами, Wi-Fi по умолчанию передает пакет в LWIP просто по указателю. Параметры. Увеличение размера или количества упомянутых выше буферов может улучшить производительность Wi-Fi. Между тем это уменьшит количество доступной памяти для приложения. Ниже дано введение параметры, которые нужно сконфигурировать пользователям: В направлении RX: CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM Этот параметр показывает количество буферов DMA на слое аппаратуры. Увеличение этого параметра повысит пропускную способность одновременного приема, повышая тем самым для стека протокола Wi-Fi возможность обработать плотный трафик. CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM Этот параметр показывает количество буферов RX на слое Wi-Fi. Увеличение этого параметра повысит производительность приема пакета. Этот параметр должен соответствовать размеру буфера RX слоя LWIP. CONFIG_ESP32_WIFI_RX_BA_WIN Этот параметр показывает размер окна AMPDU (AMPDU BA Window) на стороне приема. Этот параметр должен конфигурироваться в меньшее из значений 2 * CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM и CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM. CONFIG_LWIP_TCP_WND_DEFAULT Этот параметр представляет размер буфера RX слоя LWIP для каждого потока TCP. Это значение должно быть сконфигурировано в WIFI_DYNAMIC_RX_BUFFER_NUM(KB), чтобы достичь высокой и стабильной производительности. Тем не менее, в случае нескольких потоков это значение должно быть пропорционально уменьшено. В направлении TX: CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM Этот параметр показывает тип буфера TX. Рекомендуется сконфигурировать его в качестве динамического буфера, что позволит в полной мере использользовать память. CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM Этот параметр показывает количество буферов TX на слое Wi-Fi. Увеличение этого параметра улучшит производительность отправки пакета. Этот параметр должен соответствовать размеру буфера TX слоя LWIP. CONFIG_LWIP_TCP_SND_BUF_DEFAULT Этот параметр представляет размер буфера TX слоя LWIP для каждого потока TCP. Это значение должно быть сконфигурировано в WIFI_DYNAMIC_TX_BUFFER_NUM(KB) для достижения высокой и стабильной производительности. В случае нескольких потоков это значение должно быть пропорционально уменьшено. Замечание: для оптимизации производительности поместите код в в IRAM. Упомянутый выше буфер имеет фиксированный размер 1.6 KB. Как конфигурировать параметры. Память ESP32-C3 совместно используется стеком протоколов и приложениями. Здесь у нас есть несколько рангов конфигураций. В большинстве случаев пользователь должен выбрать подходящий ранг для конфигурации параметров в соответствии с тем, сколько памяти занято приложением. Параметры, не упомянутые в следующей таблице, должны быть установлены в значения по умолчанию. Таблица 15. Параметры, которые не должны быть установлены в значения по умолчанию.
Примечание: тест был выполнен в одном потоке на модуле с экраном, при использовании роутера ASUS RT-N66U. Одноядерный ESP32-C3 CPU работал на частоте 160 МГц, память SPI flash ESP32-C3 была подключена в режиме QIO на частоте 80 МГц. Предлагаемые ранги: Iperf. Ранг ESP32-C3 экстремальной производительности. Default. Ранг конфигурации по умолчанию ESP32-C3, доступная память и производительность сбалансированы. Minimum. Это ранг минимальной конфигурации ESP32-C3. Стек протоколов использует только необходимое для работы количество памяти. Этот вариант подходит для сценариев, когда нет особых требований к производительности, и приложению требуется повышенное количество памяти. [Устранение проблем] Для этого ознакомьтесь с отдельным документом Espressif Wireshark User Guide [8]. [Словарик] AC Access Category, категория качества доступа. Термин относится к поддержке QoS для Wi-Fi. AMPDU Aggregated Mac Protocol Data Unit [12], специальная фича, предназначенная для более экономного использования полосы пропускания канала, что позволяет увеличить пропускную способность (см. также AMSDU). AMSDU Aggregated MAC Service Data Units [12], специальная фича, предназначенная для более экономного использования полосы пропускания канала, что позволяет увеличить пропускную способность (см. также AMPDU). AP режим работы драйвера, когда ESP32-C3 работает как точка доступа (Access Point) Wi-Fi. BB Beacon Broadcaster, блок широковещательного маяка. BSSID Basic Service Set Identification, MAC-адрес беспроводного сетевого адаптера точки доступа [11]. CSD Cyclic Shift Delay, или задержка с циклическим сдвигом. Применяется в технологии Cyclic Shift Diversity, что означает разнесение с циклическим сдвигом, метод разнесения передачи, определенный в стандарте 802.11n. CSI Channel State Information, информация о состоянии канала. dBm децибел-милливатт, единица измерения мощности принимаемого сигнала. 0 dBm соответствует 1 милливатту, а значение в dBm показывает относительное изменение от этого значения в большую или меньшую сторону, по логарифмическому закону. Изменение в 2 раза означает, что надо отнять или прибавить 3 dBm. Примеры мощностей: 125 мВт соответствует 21 dBm, 500 мВт соответствует 27 dBm, 1000 мВт (1 Вт) соответствует 30 dBm. HT-LTF High Throughput LTF Long Training Field. LLTF Legacy Long Training Field. MPDU MAC protocol data unit [12]. NVS Non-Volatile Storage, энергонезависимое хранилище данных. PBUF Packet BUFfer, буфер для временного хранения данных пакета. PHY PHYsical, в данном контексте это физический интерфейс (аппаратура) трансивера, который обеспечивает низкоуровневую среду передачи и приема данных. QoS Quality of Service, маркировка трафика для поддержки передачи данных с определенным приоритетом. RF Radio Frequency, радиочастота. RSSI Received Signal Strength Indicator, индикатор уровня принимаемого сигнала. Измеряется в децибел-милливаттах (dBm). RX радиоприем. STBC-HT-LTF Space Time Block Code HT-LTF. Station режим работы драйвера, когда ESP32-C3 работает как станция Wi-Fi. Station+AP режим работы драйвера, когда ESP32-C3 работает и как станция, и как точка доступа Wi-Fi. TBTT Target Beacon Transmission Time, целевое время передачи маяка [9]. TX передача по радиоканалу. WFA Wi-Fi Alliance, торговая группа, продвигающая оборудование IEEE 802.11. [Ссылки] 1. ESP-IDF Wi-Fi Driver site:espressif.com. |