ESP-32 WIFI ST模式
学习ESP-32 WIFI 中的 st(station)手动连接一共涉及两个知识点,一个是idf的网络初始化架构,另一个是freeRTOS的事件组。
先上代码:
1.初始化
static esp_err_t wifi_init_sta(void)
{s_wifi_event_group = xEventGroupCreate();// 初始化网络接口esp_netif_init();esp_event_loop_create_default();esp_netif_create_default_wifi_sta();// 初始化Wi-Fi驱动wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));// 注册事件处理器esp_event_handler_instance_t instance_any_id;esp_event_handler_instance_t instance_got_ip;ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,&instance_any_id));ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,IP_EVENT_STA_GOT_IP,&wifi_event_handler,NULL,&instance_got_ip));// 配置Wi-Fi参数wifi_config_t wifi_config = {.sta = {.ssid = WIFI_SSID,.password = WIFI_PASS,.threshold.authmode = WIFI_AUTH_WPA2_PSK,},};ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "正在连接Wi-Fi: %s", WIFI_SSID);// 等待连接结果EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,pdFALSE,pdFALSE,WIFI_CONNECT_TIMEOUT / portTICK_PERIOD_MS);// 处理连接结果if (bits & WIFI_CONNECTED_BIT) {ESP_LOGI(TAG, "Wi-Fi连接成功");return ESP_OK;} else if (bits & WIFI_FAIL_BIT) {ESP_LOGE(TAG, "Wi-Fi连接失败(重试3次后)");return ESP_FAIL;} else {ESP_LOGE(TAG, "Wi-Fi连接超时(%dms)", WIFI_CONNECT_TIMEOUT);return ESP_FAIL;}
}
wifi事件处理函数:
static void wifi_event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{static int s_retry_num = 0;if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect();} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {if (s_retry_num < 3) {esp_wifi_connect();s_retry_num++;ESP_LOGI(TAG, "Wi-Fi断开,重试连接(第%d次)", s_retry_num);} else {xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);}ESP_LOGI(TAG, "等待Wi-Fi连接...");} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;ESP_LOGI(TAG, "获取IP地址: " IPSTR, IP2STR(&event->ip_info.ip));s_retry_num = 0;xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);}
}
代码顺序:
一.首先是初始化底层的:
文字描述:
1.创建网络的时间组 -> 2.初始化网络接口框架 -> 3.创建网络事件循环(乐鑫自己创建的任务和队列)-> 4.创建网络接口
api函数描述:
1.xEventGroupCreate() -> 2.esp_netif_init() -> 3.esp_event_loop_create_default-> 4.sp_netif_create_default_wifi_sta
二.接着是wifI的驱动与事件配置:
文字描述:
1.初始化wifi -> 2.注册事件处理器(用以处理网络事件循环产生的事件)
api描述:
1.esp_wifi_init(&cfg)
2.esp_err_t esp_event_handler_instance_register( esp_event_base_t event_base,
int32_t event_id,
esp_event_handler_t event_handler,
void *event_handler_arg,
esp_event_handler_instance_t *context)
三是wifi的应用层相关的
文字描述:
1.配置wifi连接参数(id和密码)->2.设置wifi模式(st和at)->3.应用wifi配置->4.启动wifi驱动 ->5.在事件处理函数中手动连接->6.等待事件组
api描述:
1.wifi_config_t 变量设置 -> 2.esp_wifi_set_mode() -> 3.esp_wifi_set_config() -> 4.esp_wifi_start() ->5.esp_wifi_connect()
6.xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait )
更多问题
1.ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
&instance_any_id));
请深挖以下这个函数并告诉我WIFI_EVENT信号是从哪里获得的?
答:1.核心作用是在事件系统中“登记一个关联的关系”,当指定的事件类型的具体事件发生时,调用对应的处理函数
2.event是事件类型组(WIFI EVENT IP_EVENT ETH_EVENT )
3.event_id是event_base下的具体事件了 (WIFI_EVENT_STA_START WIFI_EVENT_STA_DISCONNECT)这里的ESP_EVENT_ANY_ID表示监听所有
4.NULL 表示不传入参数
5.instance_any_id用以表示,方便后续 esp_event_handler_instance_unregister销毁
6.WIFI_EVENT信号的根源由esp_wifi_start()等api函数,发送到esp_event_loop的事件队列中,通过其产生的队列中取出
---------------------------------------------------------------------------------------------------------------------------------
2.if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
这一段是在哪里触发的?
答: 1.会在esp_wifi_start之后启动wifi硬件驱动和相关协议栈的过程中产生如果成功系统会自动发送WIFI_EVENT_STA_START等事件
---------------------------------------------------------------------------------------------------------------------------------
3.我看了有esp_wifi_start()这个函数为什么还要再esp_wifi_connect()?
答:1.前者负责硬件启动(硬件和驱动)是设备从未激活到就绪,而后者是主动发起连接