Wi-Fi 库
https://www.daobanmojie.com/109.html
介绍
Wi-Fi 库手册
Wi-Fi 的头文件地址位于 esp_wifi/include/esp_wifi.h
Wi-Fi 库支持配置及监控 ESP32 Wi-Fi 连网功能。
无线接入点(AP):也就是无线接入点,是一个无线网络的创建者,是网络的中心节点。一般家庭或办公室使用的无线路由器就一个AP。
站点(STA 或Station ):每一个连接到无线网络中的终端(如笔记本电脑、PDA及其它可以联网的用户设备)都可称为一个站点。
支持配置:
- 基站模式(即 STA 模式或 Wi-Fi 客户端模式),此时 ESP32 连接到接入点 (AP)。
- AP 模式(即 Soft-AP 模式或接入点模式),此时基站连接到 ESP32。
- AP-STA 共存模式(ESP32 既是接入点,同时又作为基站连接到另外一个接入点)。
- 上述模式的各种安全模式(WPA、WPA2 及 WEP 等)。
- 扫描接入点(包括主动扫描及被动扫描)。
- 使用混杂模式监控 IEEE802.11 Wi-Fi 数据包。
WiFi station 配置流程
Wi-Fi/LwIP 初始化阶段
- 主任务通过调用函数
esp_netif_init()
创建一个 LwIP 核心任务,并初始化 LwIP 相关工作。 - 主任务通过调用函数
esp_event_loop_create()
创建一个系统事件任务,并初始化应用程序事件的回调函数。在此情况下,该回调函数唯一的动作就是将事件中继到应用程序任务中。 - 主任务通过调用函数
esp_netif_create_default_wifi_ap()
或esp_netif_create_default_wifi_sta()
创建有 TCP/IP 堆栈的默认网络接口实例绑定 station 或 AP。 - 主任务通过调用函数
esp_wifi_init()
创建 Wi-Fi 驱动程序任务,并初始化 Wi-Fi 驱动程序。 - 主任务通过调用 OS API 创建应用程序任务。
2.Wi-Fi 配置阶段
Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景下,Wi-Fi 驱动程序处于 station 模式。
首先您需调用函数 esp_wifi_set_mode(WIFI_MODE_STA)
将 Wi-Fi 模式配置为 station 模式。可通过调用其它 esp_wifi_set_xxx API 进行更多设置,一般在建立 Wi-Fi 连接之前配置 Wi-Fi。如果在 Wi-Fi 建立连接后配置,则会因为调用 API 导致 Wi-Fi 连接断开。
如果 menuconfig 已使能 Wi-Fi NVS flash,则不论当前阶段还是后续的 Wi-Fi 配置信息都将被存储至该 flash 中。那么,当主板上电/重新启动时,就不需从头开始配置 Wi-Fi 驱动程序。您只需调用函数 esp_wifi_get_xxx
API 获取之前存储的配置信息。当然,如果不想使用之前的配置,您依然可以重新配置 Wi-Fi 驱动程序。
3.Wi-Fi 启动阶段
- 调用函数
esp_wifi_start()
启动 Wi-Fi 驱动程序。 - Wi-Fi 驱动程序将事件 WIFI_EVENT_STA_START 发布到事件任务中,然后,事件任务将执行一些正常操作并调用应用程序的事件回调函数。
- 应用程序的事件回调函数将事件 WIFI_EVENT_STA_START 中继到应用程序任务中。推荐您此时调用函数
esp_wifi_connect()
进行 Wi-Fi 连接。当然,您也可以等待在 WIFI_EVENT_STA_START 事件发生后的其它阶段再调用此函数。
4.Wi-Fi 连接阶段
- 调用函数
esp_wifi_connect()
后,Wi-Fi 驱动程序将启动内部扫描/连接过程。 - 如果内部扫描/连接过程成功,将产生 WIFI_EVENT_STA_CONNECTED 事件。然后,事件任务将启动 DHCP 客户端服务,最终触发 DHCP 程序。
- 在此情况下,应用程序的事件回调函数会将 WIFI_EVENT_STA_CONNECTED 事件中继到应用程序任务中。通常,应用程序不需进行操作,而您可以执行任何动作,例如:打印日志等。
- 中 Wi-Fi 连接可能会由于某些原因而失败,例如:密码错误、未找到 AP 等。这种情况下,将引发 WIFI_EVENT_STA_DISCONNECTED 事件并提示连接错误原因。有关如何处理中断 Wi-Fi 连接的事件,请参阅下文阶段 6 的描述。
5.Wi-Fi 获取 IP 阶段
- 一旦步骤 4.2 中的 DHCP 客户端初始化完成,Wi-Fi 驱动程序将进入 获取 IP 阶段。
- 如果 Wi-Fi 成功从 DHCP 服务器接收到 IP 地址,则将引发 IP_EVENT_STA_GOT_IP 事件,事件任务将执行正常处理。
- 应用程序的事件回调函数将事件 IP_EVENT_STA_GOT_IP 中继到应用程序任务中。对于那些基于 LwIP 构建的应用程序,此事件较为特殊,因为它意味着应用程序已准备就绪,可以开始任务,例如:创建 TCP/UDP 套接字等。此时较为容易犯的一个错误就是在接收到 IP_EVENT_STA_GOT_IP 事件之前就初始化套接字。切忌在接收到 IP 之前启动任何套接字相关操作。
6.Wi-Fi 断开阶段
- 当 Wi-Fi 因为某些原因(例如:AP 掉电、RSSI 较弱等)连接中断时,将产生 WIFI_EVENT_STA_DISCONNECTED 事件。此事件也可能在上文阶段 3 中发生。在这里,事件任务将通知 LwIP 任务清除/移除所有 UDP/TCP 连接。然后,所有应用程序套接字都将处于错误状态。也就是说,WIFI_EVENT_STA_DISCONNECTED 事件发生时,任何套接字都无法正常工作。
- 上述情况下,应用程序的事件回调函数会将 WIFI_EVENT_STA_DISCONNECTED 事件中继到应用程序任务中。推荐您调用函数
esp_wifi_connect()
重新连接 Wi-Fi,关闭所有套接字,并在必要时重新创建套接字。请参阅 WIFI_EVENT_STA_DISCONNECTED。
7.Wi-Fi IP 更改阶段
- 如果 IP 地址发生更改,将引发 IP_EVENT_STA_GOT_IP 事件,其中 “ip_change” 被置为 “true”。
- 此事件对应用程序至关重要。这一事件发生时,适合关闭所有已创建的套接字并进行重新创建。
8.Wi-Fi 清理阶段
- 调用函数
esp_wifi_disconnect()
断开 Wi-Fi 连接。 - 调用函数
esp_wifi_stop()
终止 Wi-Fi 驱动程序。 - 调用函数
esp_wifi_deinit()
清理 Wi-Fi 驱动程序。
API 参考
esp_netif_init
原型:esp_err_t esp_netif_init (void)
功能: 初始化底层TCP/IP堆栈。这个函数应该在应用程序启动时从应用程序代码中精确地调用一次。
esp_event_loop_create
原型:esp_err_t esp_event_loop_create (const esp_event_loop_args_t *event_loop_args ,esp_event_loop_handle_t *event_loop )
功能: 创建一个新的事件循环。
参数:
[in] event_loop_args
:要创建的事件循环的配置结构。
[out] event_loop
:所创建事件循环的句柄。
*esp_netif_create_default_wifi_ap
原型:esp_netif_t *esp_netif_create_default_wifi_ap (void)
功能: 创建默认的WIFI AP。在任何初始化错误的情况下,该API终止。
返回:指向esp-netif实例的指针。
*esp_netif_create_default_wifi_sta
原型:esp_netif_t *esp_netif_create_default_wifi_sta (void)
功能: 创建默认WIFI STA。在任何初始化错误的情况下,这个API中止。
返回:指向esp-netif实例的指针。
esp_wifi_deinit
原型:esp_err_t esp_wifi_deinit (void)
功能:禁用wifi函数。停止所有分配的资源,停止WiFi任务,从系统中移除WiFi驱动程序。
esp_wifi_set_mode
原型:esp_err_t esp_wifi_set_mode( wifi_mode_t mode)
功能: 设置WiFi运行模式。
设置WiFi工作模式为station模式、软AP模式或station+软AP模式。默认为“软ap模式”。
参数:
mode
:WiFi的操作模式。
esp_wifi_get_mode
原型:esp_err_t esp_wifi_get_mode( wifi_mode_t mode)
功能: 获取WiFi运行模式。
设置WiFi工作模式为station模式、软AP模式或station+软AP模式。默认为“软ap模式”。
参数:
[out] mode
:WiFi的操作模式。
esp_wifi_start
原型:esp_err_t esp_wifi_start (void)
功能: 启动WiFi根据当前配置。
当模式为WIFI_MODE_STA
时,创建station控块和启动station;
当模式为WIFI_MODE_AP
时,创建软AP控制块和启动软AP。
esp_wifi_stop
原型:esp_err_t esp_wifi_stop (void)
功能: 停止WiFi,以及相应的设置的配置块。
esp_wifi_restore
原型:esp_err_t esp_wifi_restore (void)
功能: 恢复WiFi堆栈的配置,设置为默认值。
该函数以下api所做的设置将被重置:
esp_wifi_get_auto_connect
esp_wifi_set_protocol
esp_wifi_set_config related
esp_wifi_set_mode
esp_wifi_connect
原型:esp_err_t esp_wifi_connect (void)
功能: 将ESP32通过WiFi连接到路由器(AP)。
该API只影响WIFI_MODE_STA
或`WIFI_MODE_APSTA模式。
esp_wifi_disconnect
原型:esp_err_t esp_wifi_disconnect (void)
功能: 将ESP32通过WiFi从路由器(AP)断开。
esp_wifi_scan_start
原型:esp_err_t esp_wifi_scan_start(const wifi_scan_config_t *config, bool block)
功能: 扫描所有可用的AP。
每个通道的最大主动扫描时间和被动扫描时间的值被限制为1500毫秒。超过1500ms可能导致工作站与AP断开连接,不推荐使用。
参数:
config
:扫描配置。
block
:如果block为真,这个API将阻塞调用者,直到扫描完成,否则它将立即返回。
esp_wifi_scan_stop
原型:esp_err_t esp_wifi_scan_stop (void)
功能: 停止扫描AP。
参数:
config
:扫描配置。
block
:如果block为真,这个API将阻塞调用者,直到扫描完成,否则它将立即返回。
esp_wifi_scan_get_ap_num
原型:esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number)
功能: 获取扫描到的AP的数量。
此API只能在扫描完成后调用,否则可能会得到错误的值。
参数:
[out] number
:存储扫描中找到的AP的数量。
esp_wifi_scan_get_ap_records
原型:esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number , wifi_ap_record_t *ap_records)
功能: 获取扫描到的AP的信息。
参数:
[inout] number
:存储ap_records可以保存的最大AP数。通常使用扫描到的AP的数量。
ap_records
:wifi_ap_record_t
数组来保存发现的AP
esp_wifi_set_storage
原型:esp_err_t esp_wifi_set_storage(wifi_storage_t storage)
功能: 设置WiFi API配置存储类型。默认值为WIFI_STORAGE_FLASH
,即存储在Flash。
参数:
storage
:存储类型。
枚举
esp_err_t
esp_err_t 不是枚举,而是typedef , typedef int32_t esp_err_t;
,其对应的值为宏定义。
定义 | 值 | 含义 |
---|---|---|
#define ESP_OK | 0 | esp_err_t 成功值(无错误) |
#define ESP_FAIL | -1 | 指示故障的通用 esp_err_t 代码 |
#define ESP_ERR_NO_MEM | 0x101 | 内存不足 |
#define ESP_ERR_INVALID_ARG | 0x102 | 无效的参数值 |
#define ESP_ERR_INVALID_STATE | 0x103 | 无效错误 |
#define ESP_ERR_INVALID_SIZE | 0x104 | 大小错误 |
#define ESP_ERR_NOT_FOUND | 0x105 | 未找到请求的资源 |
#define ESP_ERR_NOT_SUPPORTED | 0x106 | 操作或特性不支持 |
#define ESP_ERR_TIMEOUT | 0x107 | 操作超时 |
#define ESP_ERR_INVALID_RESPONSE | 0x108 | 收到的响应无效 |
#define ESP_ERR_INVALID_CRC | 0x109 | CRC或校验和无效 |
#define ESP_ERR_INVALID_VERSION | 0x10A | 错误版本 |
#define ESP_ERR_INVALID_MAC | 0x10B | MAC地址错误 |
#define ESP_ERR_WIFI_BASE | 0x3000 | 起始码为 WiFi 错误码 |
#define ESP_ERR_MESH_BASE | 0x4000 | 起始码为 MESH 错误码 |
#define ESP_ERR_FLASH_BASE | 0x6000 | 起始码为 flash 错误码 |
WiFi相关
定义 | 值 | 含义 |
---|---|---|
#define ESP_ERR_WIFI_NOT_INIT | ESP_ERR_WIFI_BASE + 1 | WiFi 驱动没有被 esp_wifi_init 初始化 |
#define ESP_ERR_WIFI_NOT_STARTED | ESP_ERR_WIFI_BASE + 2 | WiFi 驱动没有被 esp_wifi_start 启动 |
#define ESP_ERR_WIFI_NOT_STOPPED | ESP_ERR_WIFI_BASE + 3 | WiFi 驱动没有被 sp_wifi_stop 关闭 |
#define ESP_ERR_WIFI_IF | ESP_ERR_WIFI_BASE + 4 | WiFi 接口错误 |
#define ESP_ERR_WIFI_MODE | ESP_ERR_WIFI_BASE + 5 | WiFi 模式错误 |
#define ESP_ERR_WIFI_STATE | ESP_ERR_WIFI_BASE + 6 | WiFi 内部状态错误 |
#define ESP_ERR_WIFI_CONN | ESP_ERR_WIFI_BASE + 7 | WiFi 内部 station 或者 软AP控制块错误 |
#define ESP_ERR_WIFI_NVS | ESP_ERR_WIFI_BASE + 8 | WiFi 内部 NVS 模块错误 |
#define ESP_ERR_WIFI_MAC | ESP_ERR_WIFI_BASE + 9 | MAC地址无效 |
#define ESP_ERR_WIFI_SSID | ESP_ERR_WIFI_BASE + 10 | SSID 无效 |
#define ESP_ERR_WIFI_PASSWORD | ESP_ERR_WIFI_BASE + 11 | Password 无效 |
#define ESP_ERR_WIFI_TIMEOUT | ESP_ERR_WIFI_BASE + 12 | Timeout 错误 |
#define ESP_ERR_WIFI_WAKE_FAIL | ESP_ERR_WIFI_BASE + 13 | WiFi 处于睡眠状态(RF关闭 ,无法唤醒 |
#define ESP_ERR_WIFI_WOULD_BLOCK | ESP_ERR_WIFI_BASE + 14 | 呼叫请求被阻止 |
#define ESP_ERR_WIFI_NOT_CONNECT | ESP_ERR_WIFI_BASE + 15 | Station 仍处于断开状态 |
#define ESP_ERR_WIFI_POST | ESP_ERR_WIFI_BASE + 18 | 未能将事件发布到 WiFi 任务 |
#define ESP_ERR_WIFI_INIT_STATE | ESP_ERR_WIFI_BASE + 19 | 当init/deinit被调用时,WiFi状态无效 |
#define ESP_ERR_WIFI_STOP_STATE | ESP_ERR_WIFI_BASE + 20 | 当 WiFi 停止状态时的返回值 |
wifi_init_config_t
/*
WiFi堆栈配置参数,传递给esp_wifi_init调用。
*/
typedef struct {
system_event_handler_t event_handler; /**< WiFi 事件句柄 */
wifi_osi_funcs_t* osi_funcs; /**< WiFi OS functions */
wpa_crypto_funcs_t wpa_crypto_funcs; /**< WiFi 连接时的加密功能 */
int static_rx_buf_num; /**< WiFi 静态RX缓冲区数 */
int dynamic_rx_buf_num; /**< WiFi 动态RX缓冲区数 */
int tx_buf_type; /**< WiFi 发送区TX的类型 */
int static_tx_buf_num; /**< WiFi 静态TX缓冲区数 */
int dynamic_tx_buf_num; /**< WiFi 动态TX缓冲区数 */
int csi_enable; /**< WiFi 通道状态信息使能标志 */
int ampdu_rx_enable; /**< WiFi AMPDU RX 特性使能标志 */
int ampdu_tx_enable; /**< WiFi AMPDU TX 特性使能标志 */
int nvs_enable; /**< WiFi NVS flash 使能标志 */
int nano_enable; /**< Nano 选项的 printf/scan 系统启用标志*/
int tx_ba_win; /**< WiFi Block Ack TX window size */
int rx_ba_win; /**< WiFi Block Ack RX window size */
int wifi_task_core_id; /**< WiFi Task Core ID */
int beacon_max_len; /**< WiFi softAP maximum length of the beacon */
int mgmt_sbuf_num; /**< WiFi management short buffer number, the minimum value is 6, the maximum value is 32 */
uint64_t feature_caps; /**< Enables additional WiFi features and capabilities */
int magic; /**< WiFi init magic number, it should be the last field */
} wifi_init_config_t;
esp_event_loop_args_t
/// 用于创建事件循环的配置
typedef struct {
int32_t queue_size; /**< 事件循环队列的大小 */
const char* task_name; /**< 事件循环任务的名称;如果为空,则不会为事件循环创建专用任务*/
UBaseType_t task_priority; /**< 事件循环任务的优先级,如果任务名为空则忽略 */
uint32_t task_stack_size; /**< 事件循环任务的堆栈大小,如果任务名为空则忽略 */
BaseType_t task_core_id; /**< 事件循环任务所固定的核心,如果任务名称为空则忽略 */
} esp_event_loop_args_t;
esp_event_loop_handle_t
// typedef 定义。标识与基有关的事件的一个值
typedef void* esp_event_loop_handle_t;
wifi_mode_t
typedef enum {
WIFI_MODE_NULL = 0, /**< null mode */
WIFI_MODE_STA, /**< WiFi 使用 station 模式 */
WIFI_MODE_AP, /**< WiFi 使用 软AP 模式*/
WIFI_MODE_APSTA, /**< WiFi WiFi 使用 station+软AP 模式 */
WIFI_MODE_MAX
} wifi_mode_t;
wifi_scan_config_t
typedef struct {
uint8_t *ssid; /**< AP 的 SSID */
uint8_t *bssid; /**< AP 的 MAC 地址*/
uint8_t channel; /**< 通道,扫描特定的通道 */
bool show_hidden; /**< 启用扫描SSID被隐藏的AP */
wifi_scan_type_t scan_type; /**< 扫描类型,主动或被动 */
wifi_scan_time_t scan_time; /**< 每个通道的扫描时间 */
} wifi_scan_config_t;
值 | 描述 |
---|---|
ssid | 如果SSID不是NULL,则只能扫描具有相同SSID的AP。 |
bssid | 如果BSSID不是NULL,则只能扫描具有相同BSSID的AP。 |
channel | 如果“通道”为0,则将进行全通道扫描; 如果“通道”非0,将对指定通道进行扫描。 |
show_hidden | 如果“显示_隐藏”为0,则扫描会忽略带有隐藏SSID的AP; 值为非0,扫描会将隐藏AP视为正常AP。 |
wifi_scan_type_t scan_type | 如果“Scan_type”是WiFi_SCAN_TYPE_ACTIVE,则扫描是“主动”的;否则,它是“被动的”扫描。 |
wifi_scan_time_t scan_time | 此字段用于控制扫描在每个通道上停留多长时间。 对于被动扫描,扫描时间。被动指定每个通道的驻留时间。 对于主动扫描,每个通道的驻留时间列于下表。 在这里,min是扫描时间的缩写。active.min和max是scan_time.active.max的缩写。 min=0,max=0:扫描在每个通道上停留120 ms。 min>0,max=0:扫描在每个通道上停留120 ms。 min=0,max>0:扫描驻留在每个通道上max女士。 最小>0,最大>0:扫描停留在每个通道上的最短时间是min女士。 如果在此时间段内没有找到AP,则扫描切换到下一个通道。否则,扫描将驻留在通道上。max女士。 如果要提高扫描的性能,可以尝试修改这两个参数。 |
wifi_ap_record_t
/** 对WiFi AP的描述 */
typedef struct {
uint8_t bssid[6]; /**< AP 的 MAC 地址 */
uint8_t ssid[33]; /**< AP 的 SSID */
uint8_t primary; /**< AP 的 通道*/
wifi_second_chan_t second; /**< AP 的 辅助信道 */
int8_t rssi; /**< AP 的 讯号强度 */
wifi_auth_mode_t authmode; /**< authmode of AP */
wifi_cipher_type_t pairwise_cipher; /**< pairwise cipher of AP */
wifi_cipher_type_t group_cipher; /**< group cipher of AP */
wifi_ant_t ant; /**< antenna used to receive beacon from AP */
uint32_t phy_11b:1; /**< bit: 0 flag to identify if 11b mode is enabled or not */
uint32_t phy_11g:1; /**< bit: 1 flag to identify if 11g mode is enabled or not */
uint32_t phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */
uint32_t phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */
uint32_t wps:1; /**< bit: 4 flag to identify if WPS is supported or not */
uint32_t reserved:27; /**< bit: 5..31 reserved */
wifi_country_t country; /**< country information of AP */
} wifi_ap_record_t;