ESP32 HTTP提速:Wi-Fi参数优化指南
ESP32 HTTP提速:Wi-Fi参数优化指南
本文详细介绍了如何通过优化ESP32的Wi-Fi参数来提升HTTP性能。通过调整接收缓冲区、AMPDU配置以及CPU频率等关键参数,可以显著提高数据传输速度。文章内容专业且深入,适合对嵌入式开发和网络协议有一定了解的读者。
总体流程
下图展示了如何在接收数据方向分配或释放缓冲区:
接收数据缓冲区分配
描述:
- Wi-Fi 硬件在空中接收到数据包后,将数据包内容放到“静态接收数据缓冲区”,也就是“接收数据 DMA 缓冲区”。
- Wi-Fi 驱动程序分配一个“动态接收数据缓冲区”、复制“静态接收数据缓冲区”,并将“静态接收数据缓冲区”返回给硬件。
- Wi-Fi 驱动程序将数据包传送到上层 (LwIP),并分配一个 PBUF 用于存放“动态接收数据缓冲区”。
- 应用程序从 LwIP 接收数据。
修改前测试
ESP32-S3 Wi-Fi 的性能受许多参数的影响,各参数之间存在相互制约。如果配置地合理,不仅可以提高性能,还可以增加应用程序的可用内存,提高稳定性。这个过程可以概括为:硬件接收 -> 驱动程序复制 -> 协议栈处理 -> 应用程序接收。整个流程中,数据经过了多次“转移”,但实际的数据复制通常只发生了两次:
- 从“静态接收缓冲区”复制到“动态接收缓冲区”。
- 从“动态接收缓冲区”复制到“用户数据缓冲区”。
协议栈工作模式
ESP32-S3 数据路径
ESP32-S3 协议栈分为四层,分别为应用层、LWIP 层、Wi-Fi 层和硬件层。
- 在接收过程中,硬件将接收到的数据包放入 DMA 缓冲区,然后依次传送到 Wi-Fi 的接收数据缓冲区、LWIP 的接收数据缓冲区进行相关协议处理,最后传送到应用层。Wi-Fi 的接收数据缓冲区和 LWIP 的接收数据缓冲区默认共享同一个缓冲区。也就是说,Wi-Fi 默认将数据包转发到 LWIP 作为参考。
- 在发送过程中,应用程序首先将要发送的消息复制到 LWIP 层的发送数据缓冲区,进行 TCP/IP 封装。然后将消息发送到 Wi-Fi 层的发送数据缓冲区进行 MAC 封装,最后等待发送。
接收数据方向:
- CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM
该参数表示硬件层的 DMA 缓冲区数量。提高该参数将增加发送方的一次性接收吞吐量,从而提高 Wi-Fi 协议栈处理突发流量的能力。 - CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM
该参数表示 Wi-Fi 层中接收数据缓冲区的数量。提高该参数可以增强数据包的接收性能。该参数需要与 LWIP 层的接收数据缓冲区大小相匹配。 - CONFIG_ESP_WIFI_RX_BA_WIN
该参数表示接收端 AMPDU BA 窗口的大小,应配置为 CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM 和 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM 的二倍数值中较小的数值。 - CONFIG_LWIP_TCP_WND_DEFAULT
该参数表示 LWIP 层用于每个 TCP 流的的接收数据缓冲区大小,应配置为 WIFI_DYNAMIC_RX_BUFFER_NUM (KB) 的值,从而实现高稳定性能。同时,在有多个流的情况下,应相应降低该参数值。
可以通过以上几个参数进行调整WIFI的性能,另外还可以通过关闭节能模式、配置WiFi信道和带宽来调整:
- 禁用电源保存模式:调用
esp_wifi_set_ps(WIFI_PS_NONE)
函数,关闭 Wi-Fi 的省电功能,使 Wi-Fi 模块始终保持活跃状态,从而提高性能。 - 调整 Wi-Fi 配置:在初始化 Wi-Fi 时,使用
wifi_init_config_t
结构体,并设置适当的参数以优化性能。 - 配置 Wi-Fi 信道和带宽:选择干扰较少的信道,并设置为 40MHz 带宽,以提高数据传输速率。
修改配置
通过SDK进行修改
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=16
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=64
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=64
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
CONFIG_ESP_WIFI_TX_BA_WIN=32
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
CONFIG_ESP_WIFI_RX_BA_WIN=32
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=65535
CONFIG_LWIP_TCP_WND_DEFAULT=65535
CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
CONFIG_ESP32S3_INSTRUCTION_CACHE_WRAP=y
下面我会解释一下各个配置,可以按需修改
Wi-Fi 接收和发送缓冲区配置:
• CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=16
:设置 Wi-Fi 静态接收缓冲区的数量为 16。每个缓冲区约占用 1.6KB RAM,在调用
esp_wifi_init
时分配,直到调用
esp_wifi_deinit
时才释放。这些缓冲区用于接收所有的 802.11 帧。增加此值可以提高吞吐量,但会增加内存使用。
• CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=64
:设置 Wi-Fi 动态接收缓冲区的数量为 64。量为 64。动态缓冲区根据需要分配和释放,提供更大的灵活性以应对流量波动。
• CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=64
:设置 Wi-Fi 动态发送缓冲区的数量为 64。发送缓冲区用于存储待发送的数据帧,增加此值有助于在高流量情况下维持性能。
AMPDU(聚合 MAC 协议数据单元)配置:
• CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
:启用 Wi-Fi 的 AMPDU 发送功能,允许将多个数据帧聚合成一个更大的帧发送,从而提高吞吐量。
• CONFIG_ESP_WIFI_TX_BA_WIN=32
:设置发送端的 Block Ack(BA)窗口大小为 32。该参数表示接收端 AMPDU BA 窗口的大小,应配置为
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM
和
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM
的二倍数值中较小的数值。
tion*
• CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
:启用 Wi-Fi 的 AMPDU 接收功能,允许接收聚合的数据帧,提高接收效率。
• CONFIG_ESP_WIFI_RX_BA_WIN=32
:设置接收端的 Block Ack 窗口大小为 32。该参数表示接收端 AMPDU BA 窗口的大小,应配置为
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM
和
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM
的二倍数值中较小的数值。
lwIP(轻量级 IP 协议栈)TCP/IP 配置:
• CONFIG_LWIP_TCP_SND_BUF_DEFAULT=65535
:设置默认的 TCP 发送缓冲区大小为 65535 字节。发送缓冲区决定了在等待对方确认之前,最多可以发送的数据量。较大的缓冲区有助于提高吞吐量,但会占用更多内存。
• CONFIG_LWIP_TCP_WND_DEFAULT=65535
:设置默认的 TCP 窗口大小为 65535 字节。该参数表示 lwIP 层用于每个 TCP 流的接收数据缓冲区大小,应配置为 Wi-Fi 动态接收缓冲区数量(单位:KB)的值。
• CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
:设置 TCP 接收邮箱的大小为 64。接收邮箱用于存储接收到但尚未处理的 TCP 数据包。增大此值可以提高系统在高负载下的处理能力,但会增加内存占用。
• CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
:设置 UDP 接收邮箱的大小为 64。同样,增大此值可以提高处理能力,但会增加内存使用。
• CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
:设置 TCP/IP 任务接收邮箱的大小为 64。一般来说,较大的值意味着更高的吞吐量,但也会占用更多内存。该值应大于 UDP/TCP 邮箱的大小。
CPU 频率和 Flash 配置:
• CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
:将 CPU 默认频率设置为 240 MHz,提供更高的处理性能,但同时也会增加功耗。
• CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
:明确指定 CPU 频率为 240 MHz。
• CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
:将 Flash 模式设置为 QIO(Quad I/O),即使用四线模式进行数据传输,提高读写速度。
• CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
:将 Flash 频率设置为 80 MHz,提高 Flash 的读写性能。
ESP32-S3 指令缓存配置:
• CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
:为 ESP32-S3 配置 32KB 的指令缓存,提高指令获取速度,从而提升整体性能。
• CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
:设置指令
修改后得到日志为:
下载速度: 1712.68 KB/s
文件大小: 1029472 bytes
耗时: 587 ms
和
下载速度: 2139.03 KB/s
文件大小: 1029472 bytes
耗时: 470 ms
结论
从ESP-IDF的官方文档可以看到,最大的理论速度为86.1Mbit/s即10.7625 MB/s,可能还有优化空间,但是相对的也会极度挤占其他应用的空间,所以目前速度已经可以了