esp32之wifi狀態機
阿新 • • 發佈:2018-12-11
對於esp32模組來說,wifi是重中之重,沒有wifi的esp32絕對是個大冷門,下面來探討一下esp32wifi的工作原理:
分析程式碼,路徑esp-idf/examples/wifi/simple_wifi
#include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "nvs_flash.h" #include "lwip/err.h" #include "lwip/sys.h" /* The examples use simple WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ #define EXAMPLE_ESP_WIFI_MODE_AP CONFIG_ESP_WIFI_MODE_AP //TRUE:AP FALSE:STA #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD #define EXAMPLE_MAX_STA_CONN CONFIG_MAX_STA_CONN /* FreeRTOS event group to signal when we are connected*/ static EventGroupHandle_t wifi_event_group; /* The event group allows multiple bits for each event, but we only care about one event - are we connected to the AP with an IP? */ const int WIFI_CONNECTED_BIT = BIT0; static const char *TAG = "simple wifi"; static esp_err_t event_handler(void *ctx, system_event_t *event) { switch(event->event_id) { case SYSTEM_EVENT_STA_START: esp_wifi_connect(); break; case SYSTEM_EVENT_STA_GOT_IP: ESP_LOGI(TAG, "got ip:%s", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_AP_STACONNECTED: ESP_LOGI(TAG, "station:"MACSTR" join, AID=%d", MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid); break; case SYSTEM_EVENT_AP_STADISCONNECTED: ESP_LOGI(TAG, "station:"MACSTR"leave, AID=%d", MAC2STR(event->event_info.sta_disconnected.mac), event->event_info.sta_disconnected.aid); break; case SYSTEM_EVENT_STA_DISCONNECTED: esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); break; default: break; } return ESP_OK; } void wifi_init_softap() { wifi_event_group = xEventGroupCreate(); tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .ap = { .ssid = EXAMPLE_ESP_WIFI_SSID, .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID), .password = EXAMPLE_ESP_WIFI_PASS, .max_connection = EXAMPLE_MAX_STA_CONN, .authmode = WIFI_AUTH_WPA_WPA2_PSK }, }; if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); } void wifi_init_sta() { wifi_event_group = xEventGroupCreate(); tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .sta = { .ssid = EXAMPLE_ESP_WIFI_SSID, .password = EXAMPLE_ESP_WIFI_PASS }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK(esp_wifi_start() ); ESP_LOGI(TAG, "wifi_init_sta finished."); ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); } void app_main() { //Initialize NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); #if EXAMPLE_ESP_WIFI_MODE_AP ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); wifi_init_softap(); #else ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); #endif /*EXAMPLE_ESP_WIFI_MODE_AP*/ }
這程式碼的功能是開啟一個wifi熱點,可選擇AP模式或STA模式,程式碼的呼叫也是非常簡單的,我就不一一分析了,我直接把API呼叫流程圖放過來,一看便清楚:
按一定的流程呼叫一些API,期間需要自己設定一些自定義引數,如SSID,PASSWD等
接下來分析一下esp32wifi狀態機工作原理,注意:esp32wifi底層驅動是不開源的,這也是很多晶片廠商一貫的作法,因為開源了底層驅動,基本上也就開源了硬體引數,產品很容易被有心人複製或者盜版,以下是esp32wifi狀態機工作原理的流程圖:
可以得出結論:
1.使用者自定義狀態機回撥函式
2.回撥函式作為形參的方式傳遞給esp_event_loop_init(event_handler,NULL)函式
3.建立任務esp_event_loop_task一直監測狀態機狀態,當底層驅動傳遞過來新狀態時,自定義函式得到回撥
就這樣分析完esp32狀態機的工作原理,有興趣的可以根據上述圖表跟進原始碼