Программирование ARM ESP-IDF: драйвер Wi-Fi Mon, March 04 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

ESP-IDF: драйвер Wi-Fi Печать
Добавил(а) microsin   

Драйвером Wi-Fi поддерживаются следующие возможности:

· 4 виртуальных Wi-Fi интерфейса: STA, AP, Sniffer и reserved.
· Режимы: только станция (station-only), только точка доступа (AP-only), и совмещенный режим(station/AP-coexistence).
· Протоколы соединения IEEE 802.11b, IEEE 802.11g, IEEE 802.11n и API-функции для конфигурирования режима протокола.
· WPA/WPA2/WPA3/WPA2-Enterprise/WPA3-Enterprise/WAPI/WPS и DPP (Device Provisioning Protocol [3]).
· AMSDU, AMPDU, HT40, QoS другие ключевые функции.
· Modem-sleep.
· Специфичный для Espressif протокол ESP-NOW и режим Long Range, что позволяет передавать данные на расстоянии до 1 км.
· Полоса пропускания до 20 мегабит/сек для TCP и до 30 мегабит/сек для UDP.
· Сниффер.
· Быстрое сканирование (fast scan) и сканирование всех каналов (all-channel scan).
· Несколько антенн.
· Информация о состоянии канала.

[Как написать приложение 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):

ESP IDF WiFi driver TX buffer allocation fig01

Рис. 1. Выделение буфера передачи (TX Buffer).

Описание:

· Приложение выделяет данные, которые нужно отправить.
· Приложение для отправки данных пользователя вызывает API-функции, связанные с TCPIP/Socket. Эти вызовы API будут выделять PBUF, используемый в LwIP, и делать копию данных пользователя.
· Когда LwIP вызывает Wi-Fi API для отправки PBUF, Wi-Fi API будет выделять "Dynamic Tx Buffer" или "Static Tx Buffer", делать копию LwIP PBUF, и в завершение послать данные.

Следующая диаграмма показывает, как буфер выделяется/освобождается в направлении приема (RX):

ESP IDF WiFi driver RX buffer allocation fig02

Рис. 2. Выделение буфера приема (RX Buffer).

Описание:

· Аппаратура Wi-Fi принимает пакет по радиоканалу, и помещает его содержимое в "Static Rx Buffer", которй также называется "RX DMA Buffer".
· Драйвер Wi-Fi выделяет "Dynamic Rx Buffer", делает в него копию "Static Rx Buffer", и возвращает "Static Rx Buffer" аппаратуре.
· Драйвер Wi-Fi передает пакет на уровень выше (LwIP), и выделяет PBUF для хранения "Dynamic Rx Buffer".
· Приложение принимает данные от LwIP.

Таблица 1. Конфигурация внутреннего буфера Wi-Fi.

Тип буфера Тип выделения По умолч. Конф. Описание
Static RX Buffer (аппаратный буфер приема) Статический 10*1600 байт Да Это некий тип памяти DMA. Инициализируется в esp_wifi_init() и освобождается в esp_wifi_deinit(). 'Static Rx Buffer' формирует аппаратный список приема. При приеме кадра по радио аппаратура запишет его во внутренний буфер и сгенерирует прерывание для CPU. Затем драйвер Wi-Fi прочитает содержимое этого буфера и возвратит буфер обратно в список.

Если это необходимо, то приложение может уменьшить количество памяти, статически выделенной для Wi-Fi. Можно уменьшить это количество от 10 до 6 для экономии 6400 байт памяти. Не рекомендуется уменьшать в конфигурации значение меньше 6, если фича AMPDU не отключена.
Dynamic RX Buffer Динамический 32 Да Длина буфера это переменная величина, и она зависит от длины принятого кадра. Когда драйвер Wi-Fi принял кадр из Hardware Rx Buffer, егоо Dynamic Rx Buffer должен быть выделен из кучи. Количество Dynamic Rx Buffer, сконфигурированное в menuconfig, используется для ограничения общего количества не освобожденных динамических буферов приема.
Dynamic TX Buffer Динамический 32 Да Это некий тип памяти DMA. Он выделяется из кучи. Когда верхний слой библиотеки стека (LwIP) посылает пакеты драйверу Wi-Fi, он сначала выделяет Dynamic TX Buffer и делает туда копию буфера верхнего слоя. Динамические и статические буферы TX взаимоисключающие.
Static TX Buffer (аппаратный буфер приема) Статический 16*1600 байт Да Это некий тип памяти DMA. Инициализируется в esp_wifi_init() и освобождается в esp_wifi_deinit(). Когда верхний уровень (LwIP) посылает пакеты драйверу Wi-Fi, он сначала выделяет Static TX Buffer и делает туда копию переданных с верхнего уровня данных. Динамические и статические буферы TX взаимоисключающие. Буфер TX должен быть буфером DMA. По этой причине если PSRAM разрешена, то буфер TX должен быть статический.
Management Short Buffer Динамический 8 Нет Внутренний буфер драйвера Wi-Fi.
Management Long Buffer Динамический 32
Management Long Long Buffer Динамический 32

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:

ESP IDF WiFi driver station general scenario fig03

Рис. 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(), и оно возникает в следующих сценариях:

· Сканирование завершено, т. е. была успешно найдена целевая точка доступа, или были просканированы все каналы.
· Сканирование остановлено вызовом esp_wifi_scan_stop().
· Был вызов esp_wifi_scan_start() до завершения сканирования. Новое сканирование отменит текущее сканирование, и будет сгенерировано событие завершения сканирования (scan-done event).

Событие scan-done не возникнет в следующих сценариях:

· Это заблокированное сканирование.
· Сканирование было вызвано через esp_wifi_connect().

При получении этого события 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(), и станция уже была подключена к точке доступа.
· Когда была вызвана esp_wifi_connect(), но драйвер Wi-Fi не смог установить соединение с точкой доступа по определенным причинам, например сканирование не нашло целевую точку доступа, или произошел таймаут аутентификации. Если в эфире присутствует больше одной точки доступа с одинаковыми SSID, то событие отключения произойдет после того, как станция не сможет подключиться ко всем найденным точкам доступа.
· Когда соединение Wi-Fi было нарушено, например станция постоянно теряет N маяков, точка доступа выкинула станцию, или поменялся режим аутентификации точки доступа.

При получении этого события поведение по умолчанию следующее:

· Выключается LwIP netif станции.
· Оповещается задача LwIP для очистки соединений UDP/TCP, что приводит к неправильному статусу всех сокетов. При получении этого события для приложений, основанных на сокетах, callback приложения может выбрать либо закрыть все сокеты, либо при необходимости создать их заново.

Чаще всего обработчик этого события в приложении вызывает 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 было оборвано, и произошло событие WIFI_EVENT_STA_DISCONNECTED. В соответствии с текущей реализацией все соединения TCP будут удалены, и keep-alive сокет получит неправильный статус. Однако поскольку разработчик приложения считает, что сетевой уровень должен игнорировать эту ошибку на уровне Wi-Fi, то приложение не закроет сокет.
· Через 5 секунд соединение Wi-Fi восстановилось по причине вызова esp_wifi_connect() в callback-функции событий приложения. Кроме того, станция подключилась к той же точке доступа, и получила тот же самый адрес IPV4, что было до этого.
· 60 секунд спустя, когда приложение послало наружу данные через keep-alive сокет, этот сокет возвратил ошибку, и приложение закрыло сокет, и заново его создало, если это необходимо.

В этих показанных выше сценариях было бы идеальным не затрагивать сокеты приложения и сетевой уровень, поскольку соединение 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.
· Клиент DHCP сделал привязку к другому адресу.
· Поменялся сконфигурированный статически адрес IPV4.

Поменялся адрес 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(), чтобы вручную отключить станцию.
· Драйвер Wi-Fi отбросил станцию, например потому что точка доступа не получила никаких пакетов в течение последних 5 минут. Это время можно изменить вызовом esp_wifi_set_inactive_time().
· Станция отбросила точку доступа.

Когда это событие произошло, 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-функции.
· Восстанавливаемые ошибки, такие как ESP_ERR_NO_MEM.
· Не восстанавливаемые, не критические ошибки.
· Не восстанавливаемые, критические ошибки.

Критичность ошибки зависит от API и сценария приложения, и определяется пользователем API-функций.

Основной принцип написания надежного приложения с использованием Wi-Fi API - всегда проверять код возврата, и писать код для обработки ошибок. Обычно код обработки ошибок может использоваться:

· Для восстановимых ошибок, когда есть возможность написать код, который будет восстанавливать программу из состояния ошибки. Например, когда esp_wifi_start() вернет ESP_ERR_NO_MEM, может быть вызвана vTaskDelay, чтобы сделать нужную задержку перед другой попыткой.
· Для не восстановимых, но не критических ошибок хорошим методом будет просто печатать в лог код ошибки.
· Для не восстановимых, и в то же время критических ошибок хорошим методом будет генерировать "assert". Например, если esp_wifi_set_mode() возвратила ESP_ERR_WIFI_NOT_INIT, то это значит, что драйвер Wi-Fi не был успешно инициализирован вызовом esp_wifi_init(). Вы можете определить такого рода ошибки на фазе разработки приложения.

Заголовочный файл esp_err.h содержит макрос ESP_ERROR_CHECK, который проверяет коды возврата. Это довольно распространенный метод перехвата состояния ошибки, часто используемый в процессе разработки приложения. Однако настоятельно рекомендуется, чтобы пользователи реализовали свой код обработки ошибок.

[Инициализация параметров ESP32-C3 Wi-Fi API]

При инициализации параметров структуры для API следует придерживаться одного из двух подходов:

· Явно устанавливать все поля параметров.
· Использовать get API, чтобы сначала извлечь текущую конфигурацию, и после этого установить поля, специфичные для приложения.

Инициализация или извлечение корректного состояния всей структуры очень важно, поскольку в большинстве случаев значение поля 0 означает использование настройки по умолчанию. В будущем в структуру может быть добавлено больше полей, и инициализация их нулями будет гарантировать, что приложение все еще будет работать корректно после перехода на новый релиз ESP-IDF.

[Модель программирования ESP32-C3 Wi-Fi]

ESP IDF WiFi driver Programming Model fig04

Рис. 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. Типы сканирования.

Режим Описание
Active Scan Сканирование путем отправки probe request. Этот тип сканирования применяется по умолчанию.
Passive Scan Никакой probe request не отправляется. Просто происходит переключение на определенный канал и ожидание маяка (beacon). Приложение может разрешить это через поле scan_type в структуре конфигурации сканирования wifi_scan_config_t.
Foreground Scan Это сканирование применимо, когда в режиме станции нет Wi-Fi-соединения. Foreground или background сканирование управляется драйвером Wi-Fi, и не может быть сконфигурировано приложением.
Background Scan Это сканирование применимо, когда существует соединение Wi-Fi в режиме станции или в смешанном режиме (station/AP). Какое происходит сканирование - foreground или background - зависит от драйвера Wi-Fi, и это не может конфигурироваться приложением.
All-Channel Scan Сканирование всех каналов. Если поле channel структуры wifi_scan_config_t установлено в 0, то это задает сканирование всех каналов.
Specific Channel Scan Сканирование только определенных каналов. Если поле channel структуры wifi_scan_config_t установлено в 1-14, то это задает сканирование определенных каналов.

Режимы сканирования, приведенные в таблице выше, могут произвольно комбинироваться, в результате получается 8 различных сканирований:

· All-Channel Background Active Scan
· All-Channel Background Passive Scan
· All-Channel Foreground Active Scan
· All-Channel Foreground Passive Scan
· Specific-Channel Background Active Scan
· Specific-Channel Background Passive Scan
· Specific-Channel Foreground Active Scan
· Specific-Channel Foreground Passive Scan

Конфигурация сканирования. Тип сканирования и другие атрибуты, относящиеся к сканированию, конфигурируются esp_wifi_scan_start(). Таблица ниже предоставляет подробное описание wifi_scan_config_t.

Таблица 3. Поля конфигурации сканирования.

Поле Описание
ssid Если SSID не NULL, то могут сканироваться только те точки доступа, у которых такой же SSID.
bssid Если BSSID не NULL, то могут сканироваться только те точки доступа, у которых такой же BSSID.
channel Если channel == 0, то это задает режим сканирования всех каналов (all-channel scan); иначе будет происходить сканирование определенного (определенных) канала.
show_hidden Если show_hidden == 0, то сканирование игнорирует точки доступа со скрытыми SSID; иначе сканирование работает со скрытыми точками доступа так же, как и с обычными.
scan_type Если scan_type установлено в WIFI_SCAN_TYPE_ACTIVE, то сканирование "active", иначе оно "passive".
scan_time Это поле используется для управления длительностью сканирования на каждом канале.

Для пассивных сканирований scan_time.passive обозначает время длительности сканирования для каждого канала.

Для активных сканирований времена сканирования для каждого канала перечислены в таблице ниже. Здесь min это сокращение для time.active.min, и max сокращение для scan_time.active.max.

min=0, max=0: сканирование останавливается на каждом канале в течение 120 мс.
min>0, max=0: сканирование останавливается на каждом канале в течение 120 мс.
min=0, max>0: сканирование останавливается на каждом канале в течение max мс.
min>0, max>0: минимальное время, в течение которого сканирование задерживается на каждом канале, составляет min мс. Если за это время не была найдена ни одна точка доступа, то сканирование переключается на следующий канал. Иначе сканирование канала задерживается на max мс.

Если вы хотите улучшить производительность сканирования, то можете изменить эти 2 параметра.

Также существуют некоторые глобальные атрибуты сканирования, которые конфигурируются API-функцией esp_wifi_set_config(), см. далее "Station Basic Configuration".

Сканирование всех точек доступа на всех каналах (Foreground). Сценарий:

ESP IDF WiFi driver Foreground Scan all channels fig05

Рис. 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). Сценарий:

ESP IDF WiFi driver Background Scan all channels fig06

Рис. 6. Background Scan всех каналов Wi-Fi.

Выше показан сценарий background-сканирования всех каналов. В отличие от foreground-сканирования всех точек доступа на всех каналах, при background-сканировании драйвер Wi-Fi будет сканировать back-to-home канал в течение 30 мс перед тем, как переключится на следующий канал, чтобы дать шанс Wi-Fi-подключению передавать/принимать данные.

Сканирование определенной точки доступа на всех каналах. Сценарий:

ESP IDF WiFi driver Scan specific AP all channels fig07

Рис. 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.
· Приложение вызвало esp_wifi_connect() для повторного подключения, когда получило событие disconnect.
· Другая задача приложения, например console task, вызвала esp_wifi_scan_start() для выполнения сканирования, сканирование всегда завершается неудачей, потому что станция поддерживает соединение.
· Когда сканирование потерпело неудачу, приложение просто выполняет задержку на некоторое время, и делает повторное сканирование.

В показанных выше сценариях сканирование никогда не будет успешным, потому что станция находится в состоянии соединения. Так что если приложение подразумевает возможность подобного сценария, то оно должно предусмотреть лучшую стратегию повторного подключения. Например:

· Приложение может выбрать определение максимальных следующих друг за другом попыток переподключения с остановкой этих попыток, когда счетчик достиг максимума.
· Приложение может выбрать немедленное переподключение при первых N непрерывных переподключениях, затем дать задержку на некоторое время и снова переподключиться.
· Приложение может определить свою собственную стратегию переподключения, чтобы избежать бесполезной траты процессорного ресурса на бесконечные попытки переподключения. См. "ESP32-C3 Wi-Fi Station Connecting When Multiple APs Are Found -> Wi-Fi Reconnect" в документации [1].

[Сценарий подключения станции Wi-Fi]

Этот сценарий показывает только случай, когда на фазе сканирования найдена только одна целевая точка доступа. Для сценария, когда найдено больше одной точки доступа с одинаковыми SSID, см. "ESP32-C3 Wi-Fi Station Connecting When Multiple APs Are Found" в документации [1].

Обычно приложению не нужно заботиться о процессе подключения. Ниже приведено краткое введение в некоторые моменты процесса подключения которые могут быть интересны.

Сценарий:

ESP IDF WiFi driver Station Connecting Process fig08

Рис. 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-коды.

Reason code Значен. Отобр. Описание
UNSPECIFIED 1 1 Обычно это означает внутреннюю ошибку,  например закончилась память, сбой внутреннего TX, или reason принята от противоположной стороны.
AUTH_EXPIRE 2 2 Предыдущая аутентификация не является более допустимой. Для станции ESP эта reason сообщается в случаях:
- таймаут аутентификации.
- причина получена от AP.

Для ESP AP, эта reason сообщается в случаях:
- AP не приняла какие-либо пакеты от станции за последующие 5 минут.
- AP остановлена вызовом esp_wifi_stop().
- станция переведена в состояние de-authed (не аутентифицирована) вызовом esp_wifi_deauth_sta().
AUTH_LEAVE 3 3 De-authenticated (не аутентифицирована),  потому что отправляющая станция отключается (или отключилась).
Для станции ESP эта reason сообщается в случае: она получена от AP.
ASSOC_EXPIRE 4 4 Отключено из-за неактивности. Для станции ESP эта reason сообщается в случае: она получена от AP.

Для ESP AP эта причина сообщается в случаях:
- AP не приняла какие-либо пакеты от станции в течение 5 минут.
- AP остановлена вызовом esp_wifi_stop().
- станция переведена в состояние de-authed вызовом esp_wifi_deauth_sta().
ASSOC_TOOMANY 5 5 Отключено, потому что AP не может обработать все текущие ассоциированные STA одновременно. Для станции ESP эта reason сообщается в случае: она получена от AP.

Для ESP AP эта reason сообщается в случае: станции, ассоциированные с AP, достигли максимального количества, которое может поддержать AP.
NOT_AUTHED 6 6 От не аутентифицированной станции принят кадр Class-2. Для станции ESP эта reason сообщается в случае: она получена от AP.

Для ESP AP эта reason сообщается в случае: AP получила пакет с данными от не аутентифицированной станции.
NOT_ASSOCED 7 7 От не ассоциированной станции принят кадр Class-3. Для станции ESP эта reason сообщается в случае: она получена от AP.

Для ESP AP эта reason сообщается в случае: AP получила пакет с данными от не ассоциированной станции.
ASSOC_LEAVE 8 8 Отключено, потому что отправляющая станция оставляет (или оставила) BSS. Для станции ESP, эта reason сообщается в случае:
- она принята от AP.
- станция отключена через esp_wifi_disconnect() и другое API.
ASSOC_NOT_AUTHED 9 9 Станция, запрашивающая (повторную) ассоциацию не аутентифицирована отвечающей STA. Для станции ESP, эта reason сообщается в случае:
- она принята от AP.

Для ESP AP эта reason сообщается в случае:
- AP приняла пакеты с данными от ассоциированной, но не аутентифицированной станции.
DISASSOC_PWRCAP_BAD 10 10 Отключено, потому что недопустима информация в элементе Power Capability. Для станции ESP эта reason сообщается в случае: она получена от AP.
DISASSOC_SUPCHAN_BAD 11 11 Отключено, потому что недопустима информация в элементе Supported Channels. Для станции ESP, эта reason сообщается в случае: она принята от AP.
IE_INVALID 13 13 Недопустимый элемент, например элемент, содержимое которого не удовлетворяет спецификациями стандарта в пункте формата кадра. Для станции ESP, эта reason сообщается в случае: она принята от AP.

Для ESP AP, эта reason сообщается в случае: AP обработано неправильный WPA или RSN IE.
MIC_FAILURE 14 14 Ошибка кода целостности сообщения (MIC). Для станции ESP эта reason сообщается, в случае: она принята от AP.
4WAY_HANDSHAKE_TIMEOUT 15 15 Таймаут процесса four-way handshake. По соображениям совместимости в ESP код reason заменен на WIFI_REASON_HANDSHAKE_TIMEOUT. Для станции ESP эта reason сообщается в случае:
- таймаут handshake.
- она принята от AP.
GROUP_KEY_UPDATE_TIMEOUT 16 16 Таймаут Group-Key Handshake. Для станции ESP эта reason сообщается в случае: она принята от AP.
IE_IN_4WAY_DIFFERS 17 17 Элемент в four-way handshake отличается от кадра (Re-)Association Request/Probe и Response/Beacon frame.

Для станции ESP эта reason сообщается в случае:
- она принята от AP.
- станция обнаружила, что four-way handshake IE отличается от IE в кадре (Re-)Association Request/Probe и Response/Beacon.
GROUP_CIPHER_INVALID 18 18 Invalid group cipher. Для станции ESP эта reason сообщается в случае: она принята от AP.
PAIRWISE_CIPHER_INVALID 19 19 Недопустимый pairwise cipher. Для станции ESP эта reason сообщается в случае: она принята от AP.
AKMP_INVALID 20 20 Недопустимый AKMP. Для станции ESP эта reason сообщается в случае: - она принята от AP.
UNSUPP_RSN_IE_VERSION 21 21 Не поддерживаемая версия RSNE. Для станции ESP эта reason сообщается в случае: она принята от AP.
INVALID_RSN_IE_CAP 22 22 Недопустимые возможности RSNE. Для станции ESP эта reason сообщается в случае: она принята от AP.
802_1X_AUTH_FAILED 23 23 Ошибка аутентификации IEEE 802.1X. Для станции ESP эта reason сообщается в случае: она принята от AP.

Для ESP AP эта reason сообщается в случае: ошибка аутентификации IEEE 802.1X. 
CIPHER_SUITE_REJECTED 24 24 Подсистема чипера отклонена политиками безопасности. Для станции ESP эта reason сообщается в случае: она принята от AP.
TDLS_PEER_UNREACHABLE 25 25 Разрушение TDLS direct-link из-за того, что недоступен TDLS peer STA через прямое соединение TDLS.
TDLS_UNSPECIFIED 26 26 Разрушение TDLS direct-link по неуказанной причине.
SSP_REQUESTED_DISASSOC 27 27 Отключено, потому что сессия прервана запросом SSP.
NO_SSP_ROAMING_AGREEMENT 28 28 Отключено из-за отсутствия соглашения SSP roaming.
BAD_CIPHER_OR_AKM 29 29 Запрошенная служба отклонена из-за требований подсистемы чипера SSP или AKM requirement.
NOT_AUTHORIZED_THIS_LOCATION 30 30 Запрошенная служба не авторизована в этом месте.
SERVICE_CHANGE_PRECLUDES_TS 31 31 TS удалено, потому что у QoS AP отсутствует достаточная полоса для этой QoS STA из-за изменений характеристик службы BSS или рабочего режима (например HT BSS поменялось от канала 40 МГц на канал 20 МГц).
UNSPECIFIED_QOS 32 32 Отключение по не указанной, связанной с QoS причиной.
NOT_ENOUGH_BANDWIDTH 33 33 Отключено, потому что у QoS AP отсутствует достаточная полоса для этого QoS STA.
MISSING_ACKS 34 34 Отключено, потому что должно быть подтверждено слишком большое количество кадров, они не подтверждены из-за передач AP и/или плохих условий канала.
EXCEEDED_TXOP 35 35 Отключено, потому что STA передает вне предела её TXOP.
STA_LEAVING 36 36 Запрашивающая STA покинула BSS (или сброшена).
END_BA 37 37 Запрашивающая STA не использует больше поток или сессию.
UNKNOWN_BA 38 38 Запрашивающая STA приняла кадры с использованием механизма, для которого не была завершена настройка.
TIMEOUT 39 39 Таймаут запроса пира STA.
Reserved 40 ~ 45 40 ~ 45  
PEER_INITIATED 46 46 В отключенном кадре: отключено, потому что достигнут предел авторизованного доступа.
AP_INITIATED 47 47 В отключенном кадре: отключена из-за требований внешней службы.
INVALID_FT_ACTION_FRAME_COUNT 48 48 Недопустимый счетчик кадров FT Action.
INVALID_PMKID 49 49 Недопустимый идентификатор парного мастер-ключа (PMKID).
INVALID_MDE 50 50 Недопустимый MDE.
INVALID_FTE 51 51 Недопустимый FTE.
TRANSMISSION_LINK_ESTABLISHMENT_FAILED 67 67 Неудача установки линка передачи на альтернативном канале.
ALTERATIVE_CHANNEL_OCCUPIED 68 68 Альтернативный канал занят.
BEACON_TIMEOUT 200 reserved Код reason Wi-Fi, специфичный для Espressif: когда станция потеряла N непрерывных beacon-ов, она разрушает соединение и сообщает эту reason.
NO_AP_FOUND 201 reserved Код reason Wi-Fi, специфичный для Espressif: когда станция не смогла просканировать целевую AP.
AUTH_FAIL 202 reserved Код reason Wi-Fi, специфичный для Espressif: неудачная аутентификация, но не из-за таймаута.
ASSOC_FAIL 203 reserved Код reason Wi-Fi, специфичный для Espressif: ассоциация была неудачной, но не по причине ASSOC_EXPIRE или ASSOC_TOOMANY.
HANDSHAKE_TIMEOUT 204 reserved Код reason Wi-Fi, специфичный для Espressif: неудача handshake для той же reason, как в случае WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT.
CONNECTION_FAIL 205 reserved Код reason Wi-Fi, специфичный для Espressif: неудачное соединение с AP.

[Конфигурация ESP32-C3 Wi-Fi]

Когда разрешено Wi-Fi NVS, вся конфигурация сохраняется во flash, иначе см. Wi-Fi NVS Flash.

Wi-Fi Mode. Вызовите esp_wifi_set_mode(), чтобы установить режим Wi-Fi.

Таблица 5. Константы режима Wi-Fi.

Режим Описание
WIFI_MODE_NULL Режим NULL: в нем внутренняя структура данных не выделена для станции и для AP, оба интерфейса станции и AP не инициализированы для RX/TX данных Wi-Fi. Обычно этот режим используется для сниффера, или когда вы хотите только остановить и станцию, и AP без вызова esp_wifi_deinit(), чтобы выгрузить весь драйвер Wi-Fi.
WIFI_MODE_STA Режим станции: в нем esp_wifi_start() будет инициализировать внутренние данные станции, интерфейс станции готов для RX и TX данных Wi-Fi. После esp_wifi_connect() станция соединится с целевой AP.
WIFI_MODE_AP Режим точки доступа (AP): в нем esp_wifi_start() будет инициализировать внутренние данные AP, интерфейс AP готов для RX/TX данных Wi-Fi. Затем драйвер Wi-Fi запускает широковещание маяков (broad-casting beacons), и AP готова к подключению к ней других станций.
WIFI_MODE_APSTA Режим совмещения станции и точки доступа на одном устройстве (station/AP coexistence): в нем esp_wifi_start() инициализирует одновременно и станцию, и точку доступа (AP). Обратите внимание, что канал внешней AP, к которому подключается станция ESP, имеет более высокий приоритет, чем канал ESP AP.

Station Basic Configuration. API-функция esp_wifi_set_config() может использоваться для конфигурирования режима станции. Следующая таблица более подробно описывает поля конфигурации.

Таблица 6. Поля конфигурации.

Поле Описание
ssid Это SSID целевой AP, к которой хочет подключиться станция.
password Пароль к целевой AP.
scan_method Для WIFI_FAST_SCAN сканирования оно заканчивается, когда была найдена первая подходящая AP, для WIFI_ALL_CHANNEL_SCAN сканирование ищет все подходящие AP на всех каналах. По умолчанию используется сканирование WIFI_FAST_SCAN.
bssid_set Если поле bssid_set установлено в 0, то станция подключается к AP, у которой SSID совпадает с полем ssid, в то время как поле bssid игнорируется. Во всех других случаях станция подключается к AP, у которой SSID совпадает с полем ssid, в то время как BSSID совпадает с полем bssid.
bssid Это поле имеет значение только когда bssid_set установлено в 1, см. описание поля bssid_set.
channel Если поле channel установлено в 0, то станция сканирует каналы 1 ~ N для поиска целевой AP; иначе станция начинает сканирование с канала, который совпадает с полем channel, и затем сканирует другие каналы для поиска целевой AP. Если вы не знаете, на каком канале работает целевая AP, то установите это поле в 0.
sort_method Это поле используется только для WIFI_ALL_CHANNEL_SCAN.

Если поле sort_method установлено в WIFI_CONNECT_AP_BY_SIGNAL, то все подходящие AP сортируются по уровню сигнала, и подключение произойдет в первую очередь к той AP, у которой самый сильный сигнал. Например, если станция хочет подключиться к AP, у которой ssid "apxx", сканирование нашло две AP, у которых ssid равно "apxx", и у первой AP уровень сигнала -90 dBm, а у второй AP -30 dBm, то станция сначала подключится ко второй AP, и не будет подключаться к первой AP за исключением случая, когда не получилось подключиться ко второй.

Если sort_method установлен в WIFI_CONNECT_AP_BY_SECURITY, то все подходящие AP сортируются по безопасности. Наример, если станция хочет подключиться к AP, у которой ssid "apxx", сканирование нашло две AP с таким ssid, безопасность первой AP установлено в open, в то время как у второй WPA2, то станции будут сначала подключаться ко второй AP.
threshold Поле threshold (порог) используется для фильтра найденной AP, если режим RSSI или security меньше чем сконфигурированный threshold, то AP будет отбрасываться.

Если RSSI установлено в 0, то это означает порог по умолчанию, который равен -127 dBm. Если порог authmode установлен в 0, то это означает порог по умолчанию, и по умолчанию authmode порог соответствует open.

Внимание: режимы безопасности 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.

Режим протокола Описание
802.11 B Вызовите esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B) для установки станци/AP в режим 802.11B-only.
802.11 BG Вызовите esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G)  для установки станции/AP в режим 802.11BG.
802.11 BGN Вызовите esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N) для установки станции/AP в режим BGN.
802.11 BGNLR Вызовите esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR) для установки станции/AP в режим BGN и специфичный для Espressif режим.
802.11 LR Вызовите esp_wifi_set_protocol (ifx, WIFI_PROTOCOL_LR) для установки станции/AP только в специфичный для Espressif режим.

Этот режим запатентован Espressif, и он может устанавливать связь на расстоянии 1 километр в пределах прямой видимости. Имейте в виду, что на обоих концах канала (станция и AP) должно использоваться устройство ESP.

Режим 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. Согласование режимов.

APSTA BGN BG B BGNLR BGLR BLR LR
BGN BGN BG B BGN BG B -
BG BG BG B BG BG B -
B B B B B B B  
BGNLR - - - BGNLR BGLR BLR LR
BGLR - - - BGLR BGLR BLR LR
BLR - - - BLR BLR BLR LR
LR - - - LR LR LR LR

В этой таблице строка соответствует режиму Wi-Fi точки доступа (AP), и столбец это режим станции Wi-Fi. Символ "-" показывает, что режимы Wi-Fi точки доступа и станции несовместимы.

По этой таблице можно сделать следующие выводы:

· Для разрешенного LR в точке доступа на основе ESP32-C3 получается несовместимость с традиционным режимом 802.11, потому что beacon посылается в режиме LR.
· Для разрешенного LR в станции ESP32-C3 и режима NOT LR only получается несовместимость с традиционным режимом 802.11.
· Если и станция, и точка доступа сделаны на основе устройств ESP32-C3, у них обоих разрешен режим LR, то режим согласования поддерживает LR.

Если согласованный режим Wi-Fi поддерживает и традициональный режим 802.11, и режим LR, то в области ответственности драйвера Wi-Fi остается автоматический выбор самой лучшей скорости (data rate) в разных режимах Wi-Fi, и приложению об этом заботиться не нужно.

Влияние LR на традиционное устросйтво Wi-Fi. Передача данных в LR rate не влияет на традиционное устройство Wi-Fi по следующим причинам:

· Процесс CCA и backoff в режиме LR соответствует спецификации 802.11.
· Традиционное устройство Wi-Fi может определить сигнал LR через CCA и выполнить backoff.

Другими словами, 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.
· Необходимо большое расстояние для соединения и передачи данных через Wi-Fi.
· Требования к полосе пропускания канал связи очень невысокие, т. е. это используется для таких целей, как дистанционное управление, передачи информации о состоянии и т. п.

Вызовите esp_wifi_set_country() для установки информации страны (country info). В следующей таблице описываются подробно поля конифгурации, для установки этих полей см. описание локальных регуляторных ограничений для 2.4 GHz RF.

Таблица 9. Поля конфигурации информации страны.

Поле Описание
cc[3] Строка кода страны (country code), эти атрибуты идентифицируют элемент country или noncountry, где работает станция/AP. Если country, то первые 2 байта этой строки кодируют 2 символа информации страны, как это описано в документе ISO/IEC3166-1.  Третий байт это одно из следующего:

- символ пробела ASCII, если правила, в соответствии с которыми станция/AP работает, охватывают все среды для текущей полосы частот в стране.
- символ ASCII 'O', если правила, в соответствии с которыми станция/AP работает, относятся только для окружения вне помещения (outdoor).
- символ ASCII 'I', если правила, в соответствии с которыми станция/AP работает, относятся только к работе внутри помещения (indoor).
- символ ASCII 'X', если станция/AP работает в объекте, не относящимся к стране (noncountry entity). Первые 2 байта noncountry entity представлены двумя символами ASCII 'XX'.
- двоичное представление текущего используемого номера таблицы Operating Class. См. Annex E, IEEE Std 802.11-2012.
schan Начальный канал (start channel), это минимальный номер канала в соответствии с правилами регулирования, на котором может работать станция/AP.
nchan Общее количество каналов в соответствии с правилами регулирования. Например, если schan=1, nchan=13, то это означает, что станция/AP может посылать данные на каналах от 1 до 13.
policy Политика страны, это поле определяет, какая информация о стране будет использоваться, если сконфигурированная информация о стране конфликтует с подключенной AP. Более подробное описание policy дано в следующей секции.

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. Влияние параметров на активное сканирование.

Режим Wi-Fi Политика (policy) Описание
Станция WIFI_COUNTRY_POLICY_AUTO Если у подключенной AP есть country IE в маяке (beacon), то country info равна country info в beacon, иначе используется country info по умолчанию.

Для сканирования:
- если schan+nchan-1 > 11: используется active scan от schan до 11, и используется passive scan от 12 до schan+nchan-1.
- если schan+nchan-1 ≤ 11: используется active scan от schan до schan+nchan-1.

Всегда имейте в виду, что если AP со скрытым SSID установлена на канал passive scan, то пассивное сканирование её не найдет. Другими словами, если приложение надеется найти AP со скрытым SSID на каждом канале, то policy информации страны должна быть сконфигурирована в WIFI_COUNTRY_POLICY_MANUAL.
WIFI_COUNTRY_POLICY_MANUAL Всегда используется сконфигурированная информация страны.

Для сканирования оно производится от канала schan до канала schan+nchan-1 с active scan.
AP WIFI_COUNTRY_POLICY_AUTO Всегда используется сконфигурированная информация страны.
WIFI_COUNTRY_POLICY_MANUAL
Совмещеннный режим (станция/AP) WIFI_COUNTRY_POLICY_AUTO Если станция не подключилась к какой-либо AP, то AP использет сконфигурированную информацию страны. Если станция подключилась к AP, то у AP такая же информация о стране, как у станции. То же самое в режиме станции с policy WIFI_COUNTRY_POLICY_AUTO.

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.
    - CHAP: Challenge Handshake Authentication Protocol.
    - MSCHAP и MSCHAP-V2.

Подробную информацию о создании сертификатов, и как запустить пример 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 в режиме станции.
· ESP32-C3 как FTM Responder в режиме SoftAP.

Измерение дистанции с использованием 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(), указывается значение в миллисекундах.
· Значение Interval по умолчанию ESP_WIFI_CONNECTIONLESS_INTERVAL_DEFAULT_MODE.
· Событие WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START будет сгенерировано в начале Interval. Поскольку Window также запускается в этот момент, на этом событии рекомендуется передача (TX).
· В состоянии connected начало Interval будет согласовано с Target Beacon Transmission Time (TBTT).

Window

· У каждого connectionless-модуля после запуска есть свое собственное окно (Window). Connectionless Modules Power-saving будут работать с самым максимальным из них.
· Window конфигурируется вызовом module_name_set_wake_window(), указывается значение в миллисекундах.
· По умолчанию значение Window максимальное.

Использование окна RF, PHY и BB в разных условиях

  Интервал
ESP_WIFI_CONNECTIONLESS_INTERVAL_DEFAULT_MODE 1 - максимум
Window 0 не используется
1 - максимум режим по умолчанию используется периодически (Window < Interval) / используется всегда (Window ≥ Interval)

Режим по умолчанию. Если 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. Пропускная способность в разных условиях использования.

Тип/пропускная способность В лаборатории Модуль в экране Утилита тестирования Версия IDF (commit ID)
Raw 802.11 Packet RX - 130 мегабит/сек Внутренний инструментарий -
Raw 802.11 Packet TX - -
UDP RX 30 мегабит/сек 50 мегабит/сек Пример iperf 15575346
UDP TX 40 мегабит/сек
TCP RX 20 мегабит/сек 35 мегабит/сек
TCP TX 37 мегабит/сек

Когда пропускная способность тестируется с помощью примера iperf, используется sdkconfig в файле examples/wifi/iperf/sdkconfig.defaults.esp32c3.

[Отправка пакета Wi-Fi 80211]

API-функция esp_wifi_80211_tx() может использоваться для следующих целей:

· Отправка маяка (beacon), probe request, probe response, action frame.
· Отправка non-QoS кадра данных.

Это не может использоваться для отправки шифрованых кадров или кадров с QoS.

Предварительные условия для использования esp_wifi_80211_tx():

· Режим Wi-Fi или Station, или AP, или Station+AP.
· Какая-либо из следующих функций возвратила ESP_OK: либо esp_wifi_set_promiscuous(true), либо esp_wifi_start(), либо обе эти функции. Причина в том, что нам нужно убедиться, что аппаратура Wi-Fi была инициализирована перед вызовом esp_wifi_80211_tx(). В ESP32-C3 оба вызова, esp_wifi_set_promiscuous(true) и esp_wifi_start() могут запустить инициализацию аппаратуры Wi-Fi.
· Предоставлены корректные параметры esp_wifi_80211_tx().

Скорость передачи данных. Если соединение Wi-Fi отсутствует, скорость передачи данных составляет 1 Мбит/с. При наличии Wi-Fi-соединения и наличии пакета от станции к точке доступа или от точки доступа к станции скорость передачи данных совпадает со скоростью передачи данных по Wi-Fi-соединению. В противном случае скорость передачи данных составляет 1 Мбит/с.

Побочные эффекты, которых надо избегать в различных сценариях. Теоретически, если мы не рассматриваем побочные эффекты, которые API накладывает на драйвер Wi-Fi или другие станции/точки доступа, мы можем послать по радио необработанный пакет 802.11, с любым MAC назначения, любым MAC источника, любым BSSID или любым другим типом пакета. Однако надежные/полезные приложения должны избегать таких побочных эффектов. В таблице ниже приведены некоторые советы/рекомендации, как избежать побочных эффектов esp_wifi_80211_tx () в различных сценариях.

Таблица 12. Советы по надежному использованию.

Сценарий Описание
Без соединения W-Fi В этом сценарии не настроено соединение Wi-Fi, так что побочные эффекты в драйвере Wi-Fi отсутствуют. Если en_sys_seq==true, то драйвер Wi-Fi отвечает за последовательность управления. Если en_sys_seq==false, то приложению нужно гарантировать, что для буфера обеспечена корректная последовательность.

Теоретически MAC-адрес может быть любым. Однако это может повлиять на другие станции/AP с таким же MAC/BSSID.

Пример побочного эффекта #1. Приложение вызвало esp_wifi_80211_tx() для отправки маяка (beacon) с BSSID == mac_x в режиме AP, однако mac_x не MAC интерфейса AP. Кроме того, существует другая AP, например, "other-AP", у которой BSSID равен mac_x. Если это произошло, то может наблюдаться "unexpected behavior" (непрогнозируемое поведение), потому что станции, которые подключились к "other-AP", не смогут разобраться с маяком от "other-AP" или esp_wifi_80211_tx().

Чтобы избежать таких побочных эффектов, рекомендуется:

- Если esp_wifi_80211_tx вызвана в режиме станции, то первый MAC должен быть multicast MAC или точно MAC целевого устройства, в то время как второй MAC должен быть у интерфейса станции.
- Если esp_wifi_80211_tx вызвана в режиме AP, то первый MAC должен быть multicast MAC или точно MAC целевого устройства, в то время как второй MAC должен быть у интерфейса AP.

Эти рекомендации относятся только к способу избежать побочных эффектов, и их можно игнорировать при наличии веских причин.
Соединение W-Fi Когда соединение Wi-Fi настроено, последовательность управляется приложением, что может повлиять на последовательность управления соединением Wi-Fi в целом. Таким образом, en_sys_seq должно быть true, иначе будет возвращено ESP_ERR_WIFI_ARG.

К этому сценарию также относятся рекомендации по MAC-адресу в сценарии "Без соединения Wi-Fi".

Если режим Wi-Fi это станция, то MAC address1 это MAC для интерфейса AP, которому подключается станция, и MAC address2 это MAC интерфейса станции - говорят, что пакет посылается от станции к AP. Иначе, если Wi-Fi в режиме AP, то MAC address1 это MAC станции, которая подключается к этой AP, и MAC address2 это MAC интерфейса AP - говорят, что пакет посылается от AP к станции. Чтобы избежать конфликта соединений Wi-Fi, применяются следующие проверки:

- Если тип пакета data, и он отправляется от станции к AP, то бит ToDS в IEEE 80211 frame control должен быть 1, и бит FromDS должен быть 0. Иначе пакет будет отброшен драйвером Wi-Fi.
- Если тип пакета data, и он отправляется от AP к станции, то бит ToDS в IEEE 80211 frame control должен быть 0, и бит FromDS должен быть 1. Иначе пакет будет отброшен драйвером Wi-Fi.
- Если пакет отправляется от станции к AP или от AP к станции, то биты Power Management, More Data и Re-Transmission должны быть 0. Иначе пакет будет отброшен драйвером Wi-Fi.

При любой ошибке при проверке будет возвращено ESP_ERR_WIFI_ARG.

[Wi-Fi Sniffer Mode]

Режим снифера Wi-Fi можно разрешить вызовом esp_wifi_set_promiscuous(). Если режим снифера разрешен, то приложение может выводить дампы следующих пакетов:

· 802.11 Management frame.
· 802.11 Data frame, включая MPDU, AMPDU, AMSDU.
· 802.11 MIMO frame. Для MIMO frame сниффер только выводит длину кадра (length frame).
· 802.11 Control 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 показан на следующей картинке:

ESP IDF WiFi driver multiple antennas selecting fig09

Рис. 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.
· В настоящее время Bluetooth® не поддерживает фичу нескольких антенн. Не используйте для Bluetooth функции, связанные с использованием нескольких антенн.

Для использования нескольких антенн рекомендуются следующие сценарии:

· В Wi-Fi режиме WIFI_MODE_STA оба режима RX/TX антенны конфигурируются в WIFI_ANT_MODE_AUTO. Драйвер Wi-Fi автоматически выберет лучшую из RX/TX антенн.
· Режим RX антенны конфигурируется в WIFI_ANT_MODE_AUTO. Режим TX антенны конфигурируется в WIFI_ANT_MODE_ANT0 или WIFI_ANT_MODE_ANT1. Приложения могут выбрать всегда для TX использовать указанную антенну, или реализовать свой собственный алгоритм для выбора TX антенны, например выбор режима TX антенны на основе информации о переключении каналов, и т. п.
· Оба режима RX/TX антенны конфигурируются в WIFI_ANT_MODE_ANT0 или WIFI_ANT_MODE_ANT1.

Конфигурация с несколькими антеннами 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.

Канал Вторичный канал none ниже выше
Информация пакета signal mode не HT HT не HT HT не HT HT
полоса канала 20 МГц 20 МГц 20 МГц 20 МГц 40 МГц 20 МГц 20 МГц
STBC не STBC не STBC STBC не STBC не STBC STBC не STBC STBC не STBC не STBC STBC
Индекс поднесущей LLTF 0~31, -32~-1 0~31, -32~-1 0~31, -32~-1 0~63 0~63 0~63 0~63 0~63 -64~-1 -64~-1 -64~-1
HT-LTF - 0~31, -32~-1 0~31, -32~-1 - 0~63 0~62 0~63, -64~-1 0~60, -60~-1 - -64~-1 -62~-1
STBC-HT-LTF - - 0~31, -32~-1 - - 0~62 - 0~60, -60~-1 - - -62~-1
Всего байт 128 256 384 128 256 380 384 612 128 256 376

Вся информация из этой таблицы находится в структуре wifi_csi_info_t.

· Вторичный канал относится к полю secondary_channel поля rx_ctrl.
· Режим сигнала относится к полю sig_mode поля rx_ctrl.
· Полоса канала относится к полю cwb поля rx_ctrl.
· STBC относится к полю stbc поля rx_ctrl.
· Общее количеств байт относится к полю len.
· CSI data соответствуют каждому типу Long Training Field (LTF), сохраненному в буфере, начинающемуся от поля buf. Каждый элемент сохраняется в 2 байтах: мнимая часть (imaginary), за которой идет реальная часть (real). Порядок для каждого элемента такой же, как в sub-carrier таблицы. Порядок LTF: LLTF, HT-LTF, STBC-HT-LTF. Однако все 3 LTF-а могут не присутствовать, в зависимости от канала и информации пакета (см. выше).
· Если поле first_word_invalid в wifi_csi_info_t равно true, то это значит, что первые 4 байта CSI data некорректные из-за аппаратных ограничений ESP32-C3.
· Дополнительная информация, наподобие RSSI, шумовой порог RF, время приема и антенна antenna, находится в поле 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.
· Если LLTF, HT-LTF или STBC-HT-LTF не разрешены с помощью вызова esp_wifi_set_csi_config(), общее количество байт CSI data будет меньше, чем в таблице. Например, если LLTF и HT-LTF не разрешены, и STBC-HT-LTF разрешен, то когда принят пакет с состоянием above/HT/40MHz/STBC, общее количество байт CSI data будет 244 ((61 + 60) * 2 + 2 = 244, результат выравнивается на 4 байта, и последние 2 байта не содержат значимой информации).

[Конфигурирование Wi-Fi Channel State Information]

Для использования Wi-Fi CSI нужно выполнить следующие шаги.

· Выберите Wi-Fi CSI в menuconfig, это находится в разделе Components config –> Wi-Fi –> WiFi CSI(Channel State Information).
· Установите callback-функцию приема CSI вызовом esp_wifi_set_csi_rx_cb().
· Сконфигурируйте CSI вызоволм esp_wifi_set_csi_config().
· Разрешите CSI вызовом esp_wifi_set_csi().

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.

IP Precedence Wi-Fi AC Поддерживается AMPDU?
6, 7 AC_VO (Voice, голос) нет
4, 5 AC_VI (Video) ДА
3, 0 AC_BE (Best Effort) ДА
1, 2 AC_BK (Background) ДА

Приложение может использовать фичу 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.
· Избегайте использовать более двух разных поддерживаемых AMPDU приоритетов (precedences), например socket A использует precedence 0, socket B использует precedence 1, socket C использует precedence 2: это будет плохим дизайном, потому что потребует больше памяти. Т. е. драйвер Wi-Fi может генерировать сессию Block Ack для каждого precedence, и это потребует больше памяти, если Block Ack определена в настройке.

[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 весьма ограничена.
· В настоящий момент по умолчанию используется динамический тип буфера в библиотеке LwIP и драйверах Wi-Fi. Это означает, что и LwIP, и Wi-Fi используют общую память вместе с приложением. Программистам следует иметь это в виду, иначе есть риск столкнуться с проблемой нехватки памяти, такой как переполнение кучи ("running out of heap memory").
· Переполнение кучи очень опасно, это приведет к непредсказуемому поведению ESP32-C3 (undefined behavior). Таким образом распределение памяти приложения должно быть тщательно спланировано.
· Пропускная способность Wi-Fi сильно зависит от конфигураций, связанных с памятью, таких как размер окна TCP (TCP window size), количество динамических буферов Wi-Fi RX/TX, и т. п.
· Пиковое потребление памяти в куче стеками ESP32-C3 LwIP/Wi-Fi может зависеть он нескольких факторов, таких как максимальное количество соединений TCP/UDP, которое может быть у приложения, и т. п.
· Также значимым фактором будет общее количество памяти, которое необходимо приложению.

По этим причинам лучше всего рассматривать специально разрабатывать конфигурацию памяти для каждого отдельного приложения.

Динамический буфер против статического. Как уже упоминалось, по умолчанию драйверы 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.
· Сконфигурированное количество динамических буферов передачи: wifi_tx_dynamic_buf_num.
· Максимальный размер пакета, который может принять драйвер Wi-Fi: wifi_rx_pkt_size_max.
· Максимальный размер пакета, который может отправить драйвер Wi-Fi: wifi_tx_pkt_size_max.

Таким образом, пиковое количество памяти кучи, которое может потребить драйвер Wi-Fi, можно вычислить по следующей формуле:

wifi_dynamic_peek_memory = (wifi_rx_dynamic_buf_num * wifi_rx_pkt_size_max)
                         + (wifi_tx_dynamic_buf_num * wifi_tx_pkt_size_max)

Как правило можно не заботится о динамических буферах под пакеты кадров управления, потому что они оказывают незначительное влияние на систему.

[Как повысить производительность Wi-Fi]

На производительность ESP32-C3 Wi-Fi влияет множество параметров, и между каждым из параметров существуют взаимозависимые ограничения. Правильно подобранная конфигурация может не только улучшить производительность, то также повысить количество доступной памяти для приложений и улучшить стабильность работы.

В этой секции мы кратко рассмотрим рабочий режим стека протоколов Wi-Fi/LWIP и объясним роль каждого параметра. Будут даны примеры нескольких рекомендуемых рангов конфигураций, пользователь может выбрать подходящий вариант в соответствии со своим сценарием использования.

Рабочий режим стека протоколов

ESP IDF WiFi driver datapath fig10

Рис. 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 просто по указателю.
· Во время передачи приложение копирует сообщения для отправки в буфер TX слоя LWIP для инкапсуляции TCP/IP. Сообщения затем будут переданы в буфер TX слоя Wi-Fi для MAC-инкапсуляции и ожидания передачи.

Параметры. Увеличение размера или количества упомянутых выше буферов может улучшить производительность 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. Параметры, которые не должны быть установлены в значения по умолчанию.

Rank iperf По умолчанию Минимум
Available memory(KB) 59 160 180
WIFI_STATIC_RX_BUFFER_NUM 20 8 3
WIFI_DYNAMIC_RX_BUFFER_NUM 40 16 6
WIFI_DYNAMIC_TX_BUFFER_NUM 40 16 6
WIFI_RX_BA_WIN 32 16 6
TCP_SND_BUF_DEFAULT(KB) 40 16 6
TCP_WND_DEFAULT(KB) 40 16 6
LWIP_IRAM_OPTIMIZATION 13 13 0
Пропускная способность TCP TX (мегабит/сек) 38.1 27.2 20.4
Пропускная способность TCP RX (мегабит/сек) 35.3 24.2 17.4
Пропускная способность UDP TX (мегабит/сек) 40.6 38.9 34.1
Пропускная способность UDP RX (мегабит/сек) 52.4 44.5 44.2

Примечание: тест был выполнен в одном потоке на модуле с экраном, при использовании роутера 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.
2ESP-NETIF.
3. Wi-Fi Easy ConnectTM (DPP) site:espressif.com.
4. esp-idf / examples / wifi site:github.com.
5. ESP-IDF Event Loop Library site:espressif.com.
6. Wi-Fi Easy ConnectTM (DPP) site:espressif.com.
7. ESP-IDF WPA2 Enterprise Example site:github.com.
8. Espressif Wireshark User Guide site:espressif.com.
9. Кадр маяка Beacon frame site:wiki5.ru.
10. ESP32: библиотека энергонезависимого хранилища данных.
11. В чем разница между SSID, ESSID, BSSID?
12. AMSDU vs AMPDU: A Brief Tutorial on WiFi Aggregation Support site:arxiv.org.
13. Cyclic Shift Diversity (CSD) site:dot11ap.wordpress.com.
14. lwIP API site:espressif.com.

 

Добавить комментарий


Защитный код
Обновить

Top of Page