ESP32的WIFI的STA模式应用&调控蓝牙和WIFI发设功率

以下相关API接口的定义可进入l乐鑫官方查看:Wi-Fi 库 - ESP32 - — ESP-IDF 编程指南 v4.4 文档

STA模式配置过程:

#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.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"


#define EXAMPLE_ESP_WIFI_SSID      CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS      CONFIG_ESP_WIFI_PASSWORD
#define EXAMPLE_ESP_MAXIMUM_RETRY  CONFIG_ESP_MAXIMUM_RETRY


#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static const char *TAG = "wifi station";

static int s_retry_num = 0;

static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    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 < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } 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, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
    }
}

void wifi_init_sta(void)
{
    s_wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());

    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    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,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_got_ip));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_PASS,
            /* Setting a password implies station will connect to all security modes including WEP/WPA.
             * However these modes are deprecated and not advisable to be used. Incase your Access point
             * doesn't support WPA2, these mode can be enabled by commenting below line */
	     .threshold.authmode = WIFI_AUTH_WPA2_PSK,

            .pmf_cfg = {
                .capable = true,
                .required = false
            },
        },
    };
    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, "wifi_init_sta finished.");
}

void app_main(void)
{
    //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);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    wifi_init_sta();
}

STA流程:

ESP32的WIFI的STA模式应用&调控蓝牙和WIFI发设功率

STA过程解析:

Wi-Fi/LwIP初始阶段

如上图中 1.1\1.2\1.3\1.4 所示,分别

  • 初始化LwIP
    创建LwIP核心任务并初始化与LwIP相关的工作。
ESP_ERROR_CHECK(esp_netif_init());
// 创建系统事件任务并初始化应用程序事件的回调函数。
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 创建具有TCP / IP堆栈的默认网络接口实例绑定基站。
esp_netif_create_default_wifi_sta();

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,
                                                    &event_handler,
                                                    NULL,
                                                    &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                    IP_EVENT_STA_GOT_IP,
                                                    &event_handler,
                                                    NULL,
                                                    instance_got_ip));
  • 初始化Wi-Fi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

Wi-Fi配置阶段

wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_PASS,
            /* Setting a password implies station will connect to all security modes including WEP/WPA.
             * However these modes are deprecated and not advisable to be used. Incase your Access point
             * doesn't support WPA2, these mode can be enabled by commenting below line */
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,

            .pmf_cfg = {
                .capable = true,
                .required = false
            },
        },
    };
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );

Wi-Fi启动阶段

调用esp_wifi_start()以启动Wi-Fi驱动程序。

Wi-Fi驱动程序将WIFI_EVENT_STA_START发布到事件任务;然后,事件任务将执行一些常规操作,并将调用应用程序事件回调函数。

应用程序事件回调函数将WIFI_EVENT_STA_START中继到应用程序任务。此时调用esp_wifi_connect()

ESP_ERROR_CHECK(esp_wifi_start());

Wi-Fi连接阶段

一旦esp_wifi_connect()被调用,Wi-Fi驱动程序将开始内部扫描/连接过程。

如果内部扫描/连接过程成功,将生成WIFI_EVENT_STA_CONNECTED。在事件任务中,它将启动DHCP客户端,该客户端最终将触发DHCP进程。

由于例如密码错误,找不到AP等原因,Wi-Fi连接可能会失败。在这种情况下,会出现WIFI_EVENT_STA_DISCONNECTED,EXAMPLE_ESP_MAXIMUM_RETRY重连次数可设置。

static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    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 < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else
        ESP_LOGI(TAG,"connect to the AP fail");
    } 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, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
    }
}

Wi-Fi“Got IP”阶段

初始化DHCP客户端后,将开始IP阶段。如果从DHCP服务器成功接收到IP地址,则将出现IP_EVENT_STA_GOT_IP,并且事件任务将执行常规处理。

在应用程序事件回调中,IP_EVENT_STA_GOT_IP被中继到应用程序任务。对于基于LwIP的应用程序,此事件非常特殊,这意味着该应用程序已准备就绪,可以开始其任务,例如创建TCP / UDP套接字等。一个非常常见的错误是在收到IP_EVENT_STA_GOT_IP之前初始化套接字。接收IP之前,请勿开始与套接字相关的工作。

蓝牙与WiFi发射功率设置:

1 Wi-Fi Tx Power 调整
修改 Wi-Fi Tx Power 有以下两种方式:

在 menuconfig 中修改 Max WiFi TX power
使用 API esp_wifi_set_max_tx_power()
1.1 在 menuconfig 中修改 Max WiFi TX power
通过修改 menuconfig -> component config -> PHY 里的 Max WiFi TX power 来调整 Wi-Fi Tx Power,最大为 20 dB。如下图:

ESP32的WIFI的STA模式应用&调控蓝牙和WIFI发设功率


1.2 使用 API esp_wifi_set_max_tx_power()
通过调用 esp_wifi_set_max_tx_power() 来修改 Wi-Fi Tx power。

2 BLE Tx Power 调整
低功耗蓝牙发射功率可通过 API esp_ble_tx_power_set() 进行设置,可参见 esp_bt.h。

注: ESP32 SDK 中默认情况下使用功率级别 4,相应的发射功率为 0 dBm。ESP32 蓝牙的发射功率从 0 到 7,共有 8 个功率级别,发射功率范围从 –12 dBm 到 9 dBm。功率电平每增加 1 时,发射功率增加 3 dBm。

上一篇:QQ拼音输入法导入的的自定义短语丢失,可尝试禁止qqpycloud.exe文件联网【待进一步测试】


下一篇:vulnhub靶机-DC7-Writeup