Skip to content

嵌入式网络接口基本知识

ESP32 API参考

以太网 API

1. 以太网驱动器

一个网络应用,首先要有一个网络驱动器. ESP32-C3 提供了多种以太网驱动器,比如: w5500. 我们要通过硬件的方式来将其配置成为一个网络驱动器.
以太网驱动器由两部分组成:MAC 和 PHY。也就是说,只要实现了这两个部分功能,就可以成为一个网络驱动器.

ESP-IDF 在宏 ETH_MAC_DEFAULT_CONFIGETH_PHY_DEFAULT_CONFIG 中为 MAC 和 PHY 提供了默认配置。

c
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();      // 应用默认的通用 MAC 配置
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();      // 应用默认的 PHY 配置
//----------
esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);

2. 安装驱动程序

有了一个网络设备,还需要将这个设备安装到系统中.
以太网驱动程序包含事件驱动模型,该模型会向用户空间发送有用及重要的事件。安装以太网驱动程序之前,需要首先初始化事件循环

c
// 初始化事件循环. 这个事件是指的网络二层的事件.
esp_event_loop_create_default(); // 创建一个在后台运行的默认事件循环
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL);
// 安装驱动程序
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // 应用默认驱动程序配置
esp_eth_handle_t eth_handle = NULL; // 驱动程序安装完毕后,将得到驱动程序的句柄
esp_eth_driver_install(&config, &eth_handle); // 安装驱动程序

3. 连接驱动程序至 TCP/IP 协议栈

现在,以太网驱动程序已经完成安装。但对应 OSI(开放式系统互连模型)来看,目前阶段仍然属于第二层(即数据链路层)。这意味着可以检测到 link up/down 事件,获得用户空间的 MAC 地址,但无法获得 IP 地址,当然也无法发送 HTTP 请求。ESP-IDF 中使用的 TCP/IP 协议栈是 LwIP,关于 LwIP 的更多信息,请参考 LwIP。

参考 ESP-NETIF

3.1 创建一个网络接口

c
esp_netif_init(); // 初始化 TCP/IP 网络接口(在应用程序中应仅调用一次)
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); // 应用以太网的默认网络接口配置
esp_netif_t *eth_netif = esp_netif_new(&cfg); // 为以太网驱动程序创建网络接口

3.2 将以太网驱动程序连接至 TCP/IP 协议栈

c
esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)); // 将以太网驱动程序连接至 TCP/IP 协议栈
esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL); // 注册用户定义的 IP 事件处理程序

3.4 启动以太网驱动程序

c
esp_eth_start(eth_handle); // 启动以太网驱动程序状态机

4. 完成

将以上步骤完成后,就可以使用 TCP/IP 协议栈了.不需要其它代码了

ESP-NETIF的使用方法

ESP-NETIF 使用指南

                       |          (A) 用户代码                   |
                       |              应用程序                   |
      .................| 初始化          设置          事件       |
      .                +----------------------------------------+
      .                   .                |           *
      .                   .                |           *
  --------+            +===========================+   *     +-----------------------+
          |            | 新建/配置   获取/设置/应用程序|   *     | 初始化                 |
          |            |                           |...*.....| 应用程序 (DHCP, SNTP)  |
          |            |---------------------------|   *     |                       |
    初始化 |            |                           |****     |                       |
    启动   |************|  事件处理程序               |*********|  DHCP                 |
    停止   |            |                           |         |                       |
          |            |---------------------------|         |                       |
          |            |                           |         |    NETIF              |
    +-----|            |                           |         +-----------------+     |
    |胶水层|---<----|---|  esp_netif_transmit       |--<------| netif_output    |     |
    |     |        |   |                           |         |                 |     |
    |     |--->----|---|  esp_netif_receive        |-->------| netif_input     |     |
    |     |        |   |                           |         + ----------------+     |
    |     |...<....|...|  esp_netif_free_rx_buffer |...<.....| 数据包 buffer          |
    +-----|     |  |   |                           |         |                       |
          |     |  |   |                           |         |         (D)           |
    (B)   |     |  |   |          (C)              |         +-----------------------+
  --------+     |  |   +===========================+                 网络堆栈
网络             |  |           ESP-NETIF
接口             |  |
驱动             |  |   +---------------------------+         +------------------+
                |  |   |                           |.........| 开启/关闭          |
                |  |   |                           |         |                  |
                |  -<--|  l2tap_write              |-----<---|  写入             |
                |      |                           |         |                  |
                ---->--|  esp_vfs_l2tap_eth_filter |----->---|  读取             |
                       |                           |         |        (A)       |
                       |            (E)            |         +------------------+
                       +---------------------------+                用户代码
                             ESP-NETIF L2 TAP