ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ESP-IDF 6.0 网络栈迁移实战指南:esp_eth、ESP-NETIF 与 lwIP 破坏性变更详解

ESP-IDF 6.0 网络栈迁移实战指南:esp_eth、ESP-NETIF 与 lwIP 破坏性变更详解 ESP-IDF 6.0 网络栈迁移实战指南esp_eth、ESP-NETIF 与 lwIP 破坏性变更详解【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idfESP-IDF v6.0 对以太网驱动、网络接口抽象层和 lwIP 协议栈进行了一系列破坏性变更涉及 PHY 硬件复位 API 签名、RMII 时钟配置方式、PTP 控制接口、netif 迭代安全机制、DHCP 服务器 DNS 选项行为以及多个废弃头文件与旧版 Ping API 的移除。读完本文你将掌握每一处变更的底层原因、对应的替代 API、可复制的迁移代码以及一份可直接执行的迁移核对清单帮助以太网与 Wi-Fi 应用平滑升级到 6.0 版本。一、esp_eth 以太网组件变更1.1esp_eth_phy_802_3_reset_hw()API 签名变更如果你基于 esp_eth_phy_802_3.c 中的公共函数自行维护以太网 PHY 驱动这是必须关注的变更esp_eth_phy_802_3_reset_hw()现在只接受一个参数PHY 对象指针不再需要reset_assert_us参数来指定复位引脚的拉低时间。// 迁移后 esp_eth_phy_802_3_reset_hw(phy_802_3);从源码实现看复位时序现在改由初始化阶段固化的内部时序配置决定。在 esp_eth_phy_802_3.h 中phy_802_3_t结构体持有两个时序字段hw_reset_assert_time_us复位引脚拉低持续时间微秒post_hw_reset_delay_ms硬件复位完成后的等待时间毫秒初始化函数esp_eth_phy_802_3_basic_phy_init()见 esp_eth_phy_802_3.c在创建 PHY 时应用这些配置若上层通过esp_eth_phy_config_t显式指定了非零值则采用之否则回落到芯片相关的默认常量PHY_RESET_ASSERTION_TIME_US与ESP_ETH_NO_POST_HW_RESET_DELAY。公共结构体 esp_eth_phy.h 中这两个字段的注释也明确了语义设为 0 表示使用芯片默认值post_hw_reset_delay_ms设为 -1 表示不等待。实际的复位动作在 esp_eth_phy_802_3.c 中实现先将reset_gpio_num切为 GPIO 功能并拉低拉低时间小于 10 ms 时用esp_rom_delay_us()精确延时否则退化为vTaskDelay()的毫秒级延时释放复位后若配置了post_hw_reset_delay_ms 0则额外等待。因此迁移要点是复位时序从调用时传参变为初始化时配置如果你依赖旧的每次调用传参行为需要改为在esp_eth_phy_config_t中设置hw_reset_assert_time_us/post_hw_reset_delay_ms再调用esp_eth_phy_802_3_reset_hw(phy_802_3)。1.2 移除 RMII 时钟 Kconfig 选项components/esp_eth中的以下 RMII 时钟 Kconfig 选项已被移除时钟配置现在只通过 EMAC 配置结构体完成被移除的选项ETH_PHY_INTERFACE_RMII、ETH_RMII_CLK_INPUT、ETH_RMII_CLK_OUTPUTETH_RMII_CLK_IN_GPIO、ETH_RMII_CLK_OUTPUT_GPIO0、ETH_RMII_CLK_OUT_GPIO迁移方式sdkconfig → 代码显式配置// Before: Configuration via Kconfig // CONFIG_ETH_RMII_CLK_INPUTy // After: Explicit configuration in code eth_esp32_emac_config_t emac_config ETH_ESP32_EMAC_DEFAULT_CONFIG(); emac_config.clock_config.rmii.clock_mode EMAC_CLK_OUT; // 或 EMAC_CLK_EXT_IN emac_config.clock_config.rmii.clock_gpio 0; // ESP32 上为 GPIO0代码层面的对应结构可以在 esp_eth_mac_esp.h 中找到emac_rmii_clock_mode_t枚举定义两种模式EMAC_CLK_EXT_INRMII 参考时钟由外部 PHY 输入和EMAC_CLK_OUTEMAC 内部 PLL 输出参考时钟。该头文件对 ESP32 还特别标注了一条勘误约束若以太网需要与 Wi-Fi 或 BT 同时工作不要选择 ESP32 自身作为 RMII 时钟输出源否则会出现时钟不稳定问题。eth_mac_clock_config_t是一个联合体rmii成员包含clock_mode与clock_gpio两个字段即上文迁移代码中使用的emac_config.clock_config.rmii路径同一联合体还预留了mii与rgmii成员RGMII 模式则配置clock_rx_gpio、clock_tx_gpio、clock_phy_ref_gpio。eth_esp32_emac_config_t见 esp_eth_mac_esp.h汇总了 SMI GPIOsmi_gpio.mdc_num/smi_gpio.mdio_num、接口类型、时钟配置、DMA 突发长度、中断优先级等全部 EMAC 级参数。对于默认宏以 ESP32 为例ETH_ESP32_EMAC_DEFAULT_CONFIG()见 esp_eth_mac_esp.h预置了 MDC23、MDIO18、RMII 外部输入时钟、GPIO0 的完整配置ESP32-P4 等平台则使用各自的 GPIO 编号MDC31、MDIO52、时钟 GPIO50。影响面使用ETH_ESP32_EMAC_DEFAULT_CONFIG()的应用无需改动做过自定义时钟配置的板级代码必须改为在 EMAC 配置结构体中显式设置或改用 ESP 组件注册表中的 Ethernet Init 组件ethernet_init来承载平台时钟配置。1.3 以太网 PHY 与以太网 SPI 模块驱动移出 ESP-IDF以太网 PHY 驱动与以太网 SPI 模块驱动已从 ESP-IDF 中删除迁移至外部仓库 esp-eth-drivers并托管在 ESP 组件注册表ESP Component Registry。以下 API 不再随 SDK 提供移除的 API类型esp_eth_phy_new_ip101PHY 驱动IP101esp_eth_phy_new_lan87xxPHY 驱动LAN8720 等esp_eth_phy_new_rtl8201PHY 驱动RTL8201esp_eth_phy_new_dp83848PHY 驱动DP83848esp_eth_phy_new_ksz80xxPHY 驱动KSZ8081/8083 等esp_eth_mac_new_dm9051SPI 以太网模块 MACesp_eth_phy_new_dm9051SPI 以太网模块 PHY 兼容层esp_eth_mac_new_ksz8851snlSPI 以太网模块 MACesp_eth_phy_new_ksz8851snlSPI 以太网模块 PHY 兼容层esp_eth_mac_new_w5500SPI 以太网模块 MACesp_eth_phy_new_w5500SPI 以太网模块 PHY 兼容层影响面直接调用上述函数的以太网应用将无法再编译通过。迁移方式通过 IDF Component Manager 为项目添加对应驱动组件使用idf.py add-dependency引入 esp-eth-drivers 仓库中提供的驱动组件然后#include esp_eth_phy_xxxx.h与esp_eth_mac_xxxx.h或者改用 Ethernet Init 组件统一管理 PHY 初始化。注意驱动以组件形式存在意味着其版本由组件依赖声明如 idf_component.yml 这类项目级声明管理而非跟随 SDK 大版本。1.4 PTPioctl 命令移除改用标准时钟 API通过esp_eth_ioctl进行的 PTP 配置与控制命令已全部移除eth_mac_esp_io_cmd_t枚举中不再包含以下命令ETH_MAC_ESP_CMD_PTP_ENABLEETH_MAC_ESP_CMD_S_PTP_TIMEETH_MAC_ESP_CMD_G_PTP_TIMEETH_MAC_ESP_CMD_ADJ_PTP_FREQETH_MAC_ESP_CMD_ADJ_PTP_TIMEETH_MAC_ESP_CMD_S_TARGET_TIMEETH_MAC_ESP_CMD_S_TARGET_CB当前源码印证了这一点esp_eth_mac_esp.h 中eth_mac_esp_io_cmd_t现在只剩三个调试类命令ETH_MAC_ESP_CMD_SET_TDES0_CFG_BITS、ETH_MAC_ESP_CMD_CLEAR_TDES0_CFG_BITS、ETH_MAC_ESP_CMD_DUMP_REGS。迁移方式改用新的 PTP 时钟 API。从 esp_eth_clock.h 的实现看新接口把 PTP 封装为标准 POSIX 时钟定义时钟标识CLOCK_PTP_SYSTEMclockid_t值为 19初始化 PTP 时钟子系统并开启 MAC 硬件时间戳后通过clock_gettime(CLOCK_PTP_SYSTEM, ...)、clock_settime(CLOCK_PTP_SYSTEM, ...)与clock_adjtime(CLOCK_PTP_SYSTEM, ...)配合ADJ_OFFSET/ADJ_FREQUENCY完成读取时间、设置时间与频率/时间调整——这与被移除的G_PTP_TIME、S_PTP_TIME、ADJ_PTP_FREQ、ADJ_PTP_TIME一一对应PTP 硬件模块本身仍可通过 EMAC 配置启用esp_eth_mac_esp.h 提供eth_mac_ptp_config_t与ETH_MAC_ESP_PTP_DEFAULT_CONFIG()默认宏默认时钟源为EMAC_PTP_CLK_SRC_XTAL并可配置clk_src_period_ns与required_accuracy_ns精度目标。完整可用的参考实现见 ethernet/ptp 示例其主程序位于 ptp_main.c。二、ESP-NETIF 变更2.1 移除废弃的esp_netif_next迭代接口不安全的废弃迭代辅助函数esp_netif_next已从 esp_netif.h 中移除。该 API 的根本问题在于迭代过程中既不锁定接口链表也不持有 TCP/IP 上下文锁一旦遍历期间其他任务创建、删除或修改 netif就可能访问到已释放的接口对象。迁移后的三种替代方案方案 A受控上下文下直接使用esp_netif_next_unsafeesp_netif_t *it NULL; while ((it esp_netif_next_unsafe(it)) ! NULL) { // use it }方案 B推荐通过esp_netif_tcpip_exec在 TCP/IP 上下文内安全迭代static esp_err_t iterate_netifs(void *ctx) { esp_netif_t *it NULL; while ((it esp_netif_next_unsafe(it)) ! NULL) { // use it } return ESP_OK; } // Execute iteration safely in TCP/IP context ESP_ERROR_CHECK(esp_netif_tcpip_exec(iterate_netifs, NULL));esp_netif_tcpip_exec()esp_netif.h会把回调投递到 lwIP 的 tcpip 线程执行回调运行期间整个 TCP/IP 栈处于静态状态此时调用esp_netif_next_unsafe()才是安全的——头文件注释也明确将其定位为 bulk search loops within TCPIP context。方案 C用esp_netif_find_if谓词搜索替代手动遍历static bool match_by_key(void *ctx, esp_netif_t *netif) { const char *wanted (const char *)ctx; const char *key esp_netif_get_ifkey(netif); return key strcmp(key, wanted) 0; } esp_netif_t *target esp_netif_find_if(match_by_key, (void *)WIFI_STA_DEF); if (target) { // use target }esp_netif_find_if()esp_netif.h接受esp_netif_find_predicate_t谓词回调与上下文指针内部处理加锁与上下文安全适合只找某一个接口的场景避免自行管理遍历与锁。2.2 DHCP 服务器 DNS 选项行为变化LWIP_DHCPS_ADD_DNS移除LWIP_DHCPS_ADD_DNS宏已被移除SoftAP 上的 DHCP 服务器下发 DNS 的行为随之改变旧行为SoftAP 运行 DHCP 服务器且未设置 DNS 选项时服务器 IP 地址会被自动作为 DNS 服务器通告给客户端。新行为只有当开发者通过esp_netif_dhcps_option()显式启用ESP_NETIF_DOMAIN_NAME_SERVER选项时DHCP 服务器才会把 SoftAP 接口当前配置的主/备 DNS 地址由esp_netif_set_dns_info()设置写入 offer若未启用该选项服务器仍下发自身 IP 作为 DNS 服务器保持旧版默认行为。迁移步骤通过esp_netif_dhcps_option()启用ESP_NETIF_DOMAIN_NAME_SERVER选项使 DHCP offer 携带 DNS 信息用esp_netif_set_dns_info()为 SoftAP 接口配置一个或多个 DNS 服务器地址若希望完全不下发任何 DNS 信息仍启用该选项但把 DNS 服务器地址配置为0.0.0.0。由此开发者可以精确选择三种策略之一复刻旧行为通告 SoftAP 自身 IP、下发自定义 DNS例如公共解析器、或彻底抑制 DNS 信息0.0.0.0。三、lwIP 协议栈变更3.1 TCP/IP 线程名称从 tiT 改为 tcpiplwIP 主 TCP/IP 线程的名称由 tiT 变更为 tcpip。源码中该名称由 lwipopts.h 中的TCPIP_THREAD_NAME宏统一定义为tcpip。如果你的工具链、调试脚本或日志分析依赖线程名 tiT 来识别 TCP/IP 线程例如 FreeRTOS 线程转储解析、崩溃日志定位需要同步更新匹配规则。3.2 移除废弃的sntp.h头文件已废弃的sntp.h在 v6.0 中移除SNTP 功能现在统一包含新头文件esp_sntp.h位于 lwip 组件。请全局替换#include sntp.h为#include esp_sntp.h。3.3 移除旧版 Ping API改用 Socket 版ping_sockv6.0 移除了以下旧版 Ping 接口与头文件esp_ping.h头文件ping.h头文件函数ping_init()、ping_deinit()、esp_ping_set_target()、esp_ping_get_target()、esp_ping_result()替代方案是 socket 版 Ping APIping_sock.h采用会话 回调模型#include ping/ping_sock.h // Create ping session esp_ping_config_t config ESP_PING_DEFAULT_CONFIG(); config.target_addr target_ip; esp_ping_callbacks_t cbs { .on_ping_success on_ping_success, .on_ping_timeout on_ping_timeout, .on_ping_end on_ping_end, }; esp_ping_handle_t ping; esp_ping_new_session(config, cbs, ping); esp_ping_start(ping);完整的可运行参考见 protocols/icmp_echo 示例其中 sdkconfig.ci 展示了该示例的 CI 配置基线。四、迁移核对清单按组件逐项核对可快速完成 6.0 升级变更项触发条件迁移动作参考esp_eth_phy_802_3_reset_hw()单参数化自研 802.3 PHY 驱动复位时序改在esp_eth_phy_config_t初始化时配置esp_eth_phy_802_3.cRMII 时钟 Kconfig 移除sdkconfig 含ETH_RMII_CLK_*在eth_esp32_emac_config_t.clock_config.rmii中显式设置clock_mode/clock_gpioesp_eth_mac_esp.hPHY/SPI 模块驱动外迁调用esp_eth_phy_new_lan87xx等 11 个 APIidf.py add-dependency引入 esp-eth-drivers 组件或改用 Ethernet Init 组件—PTP ioctl 命令移除使用ETH_MAC_ESP_CMD_PTP_*改用CLOCK_PTP_SYSTEM标准时钟 APIesp_eth_clock.h、ptp 示例esp_netif_next移除手动遍历 netif 链表改esp_netif_next_unsafeesp_netif_tcpip_exec或esp_netif_find_if谓词搜索esp_netif.hLWIP_DHCPS_ADD_DNS移除SoftAP DHCP 依赖 DNS 下发esp_netif_dhcps_option(ESP_NETIF_DOMAIN_NAME_SERVER)esp_netif_set_dns_info—tcpip 线程名变更脚本/日志匹配 tiT更新为 tcpiplwipopts.hsntp.h移除#include sntp.h替换为esp_sntp.hesp_sntp.h旧版 Ping API 移除调用ping_init等函数迁移到 socket 版ping/ping_sock.hicmp_echo 示例总体上6.0 的网络栈迁移方向非常一致把过去散落在 Kconfig、ioctl 命令和全局单例式 API 中的配置收敛到显式的 C 配置结构体、线程安全的接口封装和标准系统调用上。凡使用默认配置ETH_ESP32_EMAC_DEFAULT_CONFIG()、ESP_PING_DEFAULT_CONFIG()等的应用受影响最小只有做过时钟定制、PHY 自研、PTP 深度控制或 netif 手动遍历的代码才需要按上表逐项改造。【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表