0.前言

本文介绍ESP32C3 WiFi 连接过程,参考乐鑫官方的乐鑫SDK的station示例
(位于wifi\getting_started\station)
ESP32C3连接WiFi可分为三个步骤。

  • 初始化WiFi(包括初始化LwIP、初始化WiFi驱动程序、初始化系统事件等)
  • 配置WiFi(设置WiFi账号密码,设置WiFi的安全方面的设置等)
  • 启动WiFi

1.初始化WiFi

  • 使用esp_netif_init()创建一个LwIP核心任务,并初始化LwIP相关工作。
  • 使用esp_event_loop_create_default()创建一个系统事件任务,并初始化应用程序事件的回调函数。
  • 使用esp_netif_create_default_wifi_sta()创建有 TCP/IP 堆栈的默认网络接口实例绑定 station
  • 使用esp_wifi_init()初始化WiFi驱动

以上的初始化为固定的初始化为固定的流程,是否理解都不影响正常的业务开发(下面的是初始化的重点)

  • 使用 esp_event_handler_instance_register()事件回调函数。

esp_event_handler_instance_register()函数有5个参数

image-20220212192555408

在乐鑫SDK的station示例中使用esp_event_handler_instance_register()函数注册了两个回调函数

  static void event_handler(void* arg,esp_event_base_t event_base,int32_t event_id, void* event_data)
  {
     /*此处略,下文有该回调函数的详细分析*/
  }
  
  
  esp_event_handler_instance_t instance_any_id;
  //注册第一个回调函数
  esp_event_handler_instance_register(WIFI_EVENT,          //设置为wifi相关的事件
                                      ESP_EVENT_ANY_ID,    //设置为所有的wifi事件(ESP_EVENT_ANY_ID=-1)
                                      &event_handler,      //回调函数
                                      NULL,                //设置为NULL没有额外的数据
                                      &instance_any_id);  
  
  esp_event_handler_instance_t instance_got_ip;
  //注册第二个回调函数
  esp_event_handler_instance_register(IP_EVENT,            //设置为ip相关的事件
                                      IP_EVENT_STA_GOT_IP, //设置为station从ap获取到ip
                                      &event_handler,
                                      NULL,
                                      &instance_got_ip);

仔细观察不难发现,两个esp_event_handler_instance_register()都注册到了同一个回调函数,当有WiFi相关的所有事件获取到ip的事件发生系统默认的循环函数将会调用event_handler()。通过event_handler()函数的event_base参数和event_id可判断出本次触发是何种事件引起的。WiFi的连接也是在回调函数中完成的,具体的过程将在下文详细分析。

2.配置WiFi

  • 使用esp_wifi_set_mode()设置WiFi模式,可设置为null模式 station模式 AP模式 station + AP模式
  • 使用esp_wifi_set_config()设置WiFi账号密码等信息,esp_wifi_set_config()有两个参数

image-20220212192523435

在乐鑫SDK的station示例中定义了wifi_config结构体

  wifi_config_t wifi_config = {
        .sta = {
              .ssid = EXAMPLE_ESP_WIFI_SSID,            //wifi账号
              .password = EXAMPLE_ESP_WIFI_PASS,        //wifi密码
              .threshold.authmode = WIFI_AUTH_WPA2_PSK, //wifi身份验证模式
  
              .pmf_cfg = {
                  .capable = true,
                  .required = false
              },
          },
      };
  
  esp_wifi_set_mode(WIFI_MODE_STA)                   //设置WiFi模式
  esp_wifi_set_config(WIFI_IF_STA, &wifi_config);    //配置WiFi

wifi_config结构体中pmf_cfg设置的是管理帧的保护模式required=true时ESP32C3强制使用加密的管理帧ESP32C3将不会连接到管理帧是未加密的路由器。

capable=true时ESP32C3不强制使用加密的管理帧,如果路由器支持加密的管理帧,就是用加密的管理帧。如果如果路由器不支持加密的管理帧,就是用不加密的管理帧。

3.启动WiFi

  • 使用esp_wifi_start()函数启动WiFi

WiFi启动后的各状态都会触发回调函数,在乐鑫SDK的station示例中定义了event_handler()回调函数。

  • 在wifi station启动后调用esp_wifi_connect()连接wifi。
  • 在wifi连接断开后调用esp_wifi_connect()连接wifi。
  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) {       //wifi station 启动
          esp_wifi_connect();        //连接wifi
      } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {  //wifi连接断开
          if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {    //判断重连次数
              esp_wifi_connect();    //连接wifi
              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) { //从ap获得ip(wifi连接成功)
          ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
          ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));         //打印wifi信息
          s_retry_num = 0;
      }
  }
文章目录