文章目录前言1. 硬件准备接线说明2. 开发环境概述工具链版本NuttX 源码3. 关键配置步骤3.1 Python 虚拟环境3.2 工具链前缀适配3.3 环境脚本4. 以太网 defconfig 定制4.1 原始 ethernet 配置分析4.2 修改为 USB 串口控制台4.3 添加自定义测试程序5. 编译5.1 CMake 配置5.2 处理兼容性问题5.3 编译6. 烧录7. 测试验证7.1 打开串口7.2 查看网络接口7.3 DHCP 获取 IP7.4 Ping 外网7.5 ethdemo TCP 测试8. SPI Flash 文件系统可选9. 已启用的网络功能一览10. 常见问题Q: ping 不通外网但能 ping 通网关Q: DHCP 获取不到 IPQ: 编译时报 stdatomic.h 相关错误Q: esptool 烧录失败11. 总结附录ethdemo 构建文件KconfigMakefileMake.defsCMakeLists.txt前言ESP32-P4 是乐鑫推出的高性能 RISC-V SoC内置以太网 MACEMAC支持有线网络连接。本文记录在 Windows 环境下基于 Apache NuttX 实时操作系统完成 ESP32-P4-Function-Ev-Board 以太网功能的编译、烧录和测试全过程。最终效果ESP32-P4 通过网线连接路由器自动获取 IP成功 Ping 通外网并完成 TCP 连接测试。1. 硬件准备ESP32-P4-Function-Ev-Board 1.6USB 数据线用于烧录和串口调试网线连接路由器或交换机电源USB 供电即可接线说明ESP32-P4-Function-Ev-Board 自带以太网 RJ45 接口只需插上网线即可。USB 口同时用于烧录和串口控制台USB CDC-ACM。2. 开发环境概述本文复用已有的 ESP-IDF 工具链只补齐 NuttX 编译所需的额外组件。工具链版本工具版本路径RISC-V GCC15.2.0C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204CMake4.0.3C:\Espressif\tools\cmake\4.0.3Ninja1.12.1C:\Espressif\tools\ninja\1.12.1esptool5.3.0C:\Espressif\tools\python\master\venv\ScriptsGit Bash—C:\Program Files\GitNuttX 源码cd D:\esp32p4-nuttx git clone--depth 1 https://github.com/apache/nuttx.git nuttx git clone--depth 1 https://github.com/apache/nuttx-apps.git apps3. 关键配置步骤3.1 Python 虚拟环境NuttX 的 Kconfig 解析需要kconfiglib建议单独创建 venvcd D:\esp32p4-nuttx python-m venv.venv.\.venv\Scripts\python.exe-m pip install kconfiglib14.1.03.2 工具链前缀适配NuttX CMake 期望的 RISC-V 工具链前缀是riscv64-unknown-elf-而 ESP-IDF 提供的是riscv32-esp-elf-。解决方案是创建符号链接或复制重命名# 创建工具目录mkdir D:\esp32p4-nuttx\tools\bin# 复制并重命名工具链$srcC:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\bin$dstD:\esp32p4-nuttx\tools\bin(gcc,g,ld,ar,objcopy,objdump,nm,size,strip)|ForEach-Object{Copy-Item$src\riscv32-esp-elf-$_.exe$dst\riscv64-unknown-elf-$_.exe}同时设置环境变量$env:GCC_EXEC_PREFIX C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\libexec\gcc\3.3 环境脚本创建env-esp32p4-nuttx.ps1一键加载环境$Root$PSScriptRoot$toolPaths ((Join-Path$Root.venv\Scripts),C:\Espressif\tools\python\master\venv\Scripts,(Join-Path$Roottools\bin),(Join-Path$Rootmingw64\bin),C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\bin,C:\Espressif\tools\cmake\4.0.3\bin,C:\Espressif\tools\ninja\1.12.1,C:\Program Files\Git\usr\bin,C:\Program Files\Git\bin)$existingToolPaths$toolPaths|Where-Object{Test-Path$_}$env:Path ($existingToolPaths-join;);$env:Path$env:GCC_EXEC_PREFIX C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\libexec\gcc\Write-HostESP32-P4 NuttX environment ready at$Root4. 以太网 defconfig 定制NuttX 为 ESP32-P4-Function-Ev-Board 提供了多个预置配置。以太网功能对应的配置是esp32p4-function-ev-board:ethernet。4.1 原始 ethernet 配置分析查看nuttx\boards\risc-v\esp32p4\esp32p4-function-ev-board\configs\ethernet\defconfig关键配置项CONFIG_ESPRESSIF_EMACy # 启用以太网 MAC CONFIG_ESPRESSIF_ETH_DMA_BUFFER_SIZE512 CONFIG_NETINIT_DHCPCy # DHCP 客户端 CONFIG_NETDB_DNSCLIENTy # DNS 解析 CONFIG_NET_TCPy # TCP 协议 CONFIG_NET_UDPy # UDP 协议 CONFIG_NET_ICMP_SOCKETy # ICMP (Ping) CONFIG_SYSTEM_PINGy # ping 命令 CONFIG_UART0_SERIAL_CONSOLEy # 默认用 UART0 作控制台4.2 修改为 USB 串口控制台默认配置使用 UART0GPIO37/38作为控制台需要外接 USB-TTL 转接器。改为 USB 串口控制台后烧录和调试都用同一根 USB 线- CONFIG_UART0_SERIAL_CONSOLEy # CONFIG_ESPRESSIF_UART0 is not set CONFIG_ESPRESSIF_USBSERIALy4.3 添加自定义测试程序在apps\examples\下创建ethdemo测试应用用于验证网络连通性apps/examples/ethdemo/ethdemo_main.c#includenuttx/config.h#includestdio.h#includestring.h#includeunistd.h#includeerrno.h#includesys/socket.h#includenetinet/in.h#includearpa/inet.h#includenet/if.h#includenetutils/netlib.h#defineETHDEMO_BUF_SIZE512#defineETHDEMO_TIMEOUT5staticvoidprint_ifinfo(FARconstchar*ifname){structin_addraddr,mask,gw;uint8_tmac[IFHWADDRLEN];printf(\n Network Interface: %s \n,ifname);if(netlib_get_ipv4addr(ifname,addr)0)printf( IP Address: %s\n,inet_ntoa(addr));if(netlib_get_ipv4netmask(ifname,mask)0)printf( Netmask: %s\n,inet_ntoa(mask));if(netlib_get_dripv4addr(ifname,gw)0)printf( Gateway: %s\n,inet_ntoa(gw));if(netlib_getmacaddr(ifname,mac)0)printf( MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);}staticinttcp_connect_test(FARconstchar*host,uint16_tport){structsockaddr_inserver;structtimevaltv;intsockfd,ret;charbuf[ETHDEMO_BUF_SIZE];constchar*http_requestGET / HTTP/1.0\r\nHost: test\r\n\r\n;ssize_tnread;printf(\n TCP Connect Test \n);printf(Connecting to %s:%u...\n,host,port);sockfdsocket(AF_INET,SOCK_STREAM,0);if(sockfd0){printf(ERROR: socket() failed\n);return-errno;}tv.tv_secETHDEMO_TIMEOUT;tv.tv_usec0;setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv));setsockopt(sockfd,SOL_SOCKET,SO_SNDTIMEO,tv,sizeof(tv));memset(server,0,sizeof(server));server.sin_familyAF_INET;server.sin_porthtons(port);inet_pton(AF_INET,host,server.sin_addr);retconnect(sockfd,(structsockaddr*)server,sizeof(server));if(ret0){printf(ERROR: connect() failed\n);close(sockfd);return-errno;}printf(Connected successfully!\n);send(sockfd,http_request,strlen(http_request),0);printf(Sent HTTP request, waiting for response...\n);nreadrecv(sockfd,buf,sizeof(buf)-1,0);if(nread0){buf[nread200?200:nread]\0;printf(Received %zd bytes:\n%s\n,nread,buf);}close(sockfd);return0;}intmain(intargc,FARchar*argv[]){FARconstchar*host(argc1)?argv[1]:192.168.1.1;uint16_tport(argc2)?(uint16_t)atoi(argv[2]):80;printf(\n\n);printf( ESP32-P4 Ethernet Network Test\n);printf(\n);print_ifinfo(eth0);tcp_connect_test(host,port);printf(\n\n);printf( Test Complete\n);printf(\n);return0;}配套的构建文件Kconfig、Makefile、Make.defs、CMakeLists.txt遵循 NuttX 应用标准结构详见文末附录。在 defconfig 中启用CONFIG_EXAMPLES_ETHDEMOy CONFIG_EXAMPLES_ETHDEMO_HOST192.168.1.1 CONFIG_EXAMPLES_ETHDEMO_PORT805. 编译5.1 CMake 配置cd D:\esp32p4-nuttx..\env-esp32p4-nuttx.ps1 cmake-S nuttx-B build-ethernet-G Ninja -DCMAKE_MAKE_PROGRAMC:\Espressif\tools\ninja\1.12.1\ninja.exe-DBOARD_CONFIGesp32p4-function-ev-board:ethernet-DNUTTX_APPS_DIRD:\esp32p4-nuttx\apps-DPython3_EXECUTABLED:\esp32p4-nuttx\.venv\Scripts\python.exe-DEXTRA_FLAGS-stdgnu115.2 处理兼容性问题stdatomic.h 兼容头ESP HAL 部分代码与当前工具链的stdatomic.h不兼容需要在以下路径放置兼容包装头build-ethernet\arch\risc-v\src\common\espressif\esp-hal-3rdparty\nuttx\src\components\esp_libc\platform_include\stdatomic.h核心内容#pragmaonce#include_nextstdatomic.h#ifdefATOMIC_VAR_INIT#undefATOMIC_VAR_INIT#endif#defineATOMIC_VAR_INIT(val)(val)#ifdefatomic_init#undefatomic_init#endif#defineatomic_init(ptr,val)__atomic_store_n((ptr),(val),__ATOMIC_RELAXED)libgcc.a复制到构建目录Copy-ItemC:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\lib\gcc\riscv32-esp-elf\15.2.0\libgcc.a-DestinationD:\esp32p4-nuttx\build-ethernet\libgcc.a5.3 编译cmake--build build-ethernet--parallel4成功输出[1666/1666] Running utility command for nuttx_post_build esptool v5.3.0 Creating ESP32-P4 image... Successfully created ESP32-P4 image. -- Generated: nuttx.bin编译产物文件大小说明nuttx771 KBELF 可执行文件nuttx.bin339 KBESP32-P4 烧录镜像nuttx.hex812 KBIntel HEX 格式nuttx.map1.9 MB链接 Map 文件6. 烧录ESP32-P4 使用 simple boot 模式烧录地址为0x2000esptool--chip esp32p4-p COM4-b 460800write-flash-fs 4MB-fm dio-ff 80m 0x2000.\build-ethernet\nuttx.bin烧录日志Connected to ESP32-P4 on COM4 Wrote 339068 bytes at 0x00002000 Hash of data verified. Hard resetting via RTS pin...7. 测试验证7.1 打开串口python-m serial.tools.miniterm COM4 115200按 RESET 或敲回车看到nsh提示符。7.2 查看网络接口nshifconfigeth0 Link encap:Ethernet HWaddr e8:f6:0a:e3:a6:46 at RUNNING mtu1500inet addr:0.0.0.0 DRaddr:10.0.0.1 Mask:255.255.255.0此时已获取到 MAC 地址但还没有 IP。7.3 DHCP 获取 IPnshrenew eth0 nshifconfigeth0 Link encap:Ethernet HWaddr e8:f6:0a:e3:a6:46 at RUNNING mtu1500inet addr:192.168.1.135 DRaddr:192.168.1.1 Mask:255.255.255.0成功通过 DHCP 获取到 IP192.168.1.135。7.4 Ping 外网nshpingwww.baidu.com PING110.242.69.2156bytes of data56bytes from110.242.69.21:icmp_seq0time10.0ms56bytes from110.242.69.21:icmp_seq1time10.0ms56bytes from110.242.69.21:icmp_seq2time10.0ms...10packets transmitted,10received,0% packet loss,time10100ms rtt min/avg/max/mdev0.000/9.000/10.000/3.000 msDNS 解析和 ICMP 全部正常10 包 0% 丢包。7.5 ethdemo TCP 测试nshethdemoESP32-P4 Ethernet Network TestNetwork Interface: eth0IP Address:192.168.1.135 Netmask:255.255.255.0 Gateway:192.168.1.1 MAC Address: e8:f6:0a:e3:a6:46TCP Connect TestConnecting to192.168.1.1:80... Connected successfully!Sent HTTP request, waitingforresponse... Received183bytes: HTTP/1.1200OK Cache-control:no-cache, no-store, max-age0Content-Type:text/html...Test CompleteTCP 连接、HTTP 请求、数据收发全部正常。8. SPI Flash 文件系统可选首次使用 SPI Flash 需要格式化nshmksmartfs /dev/smart0 nshmount-tsmartfs /dev/smart0 /mnt nshechoHello ESP32-P4/mnt/test.txt nshcat/mnt/test.txt Hello ESP32-P49. 已启用的网络功能一览功能配置项说明以太网 MACCONFIG_ESPRESSIF_EMACy内部 EMAC 外部 PHYUSB 串口CONFIG_ESPRESSIF_USBSERIALyUSB CDC-ACM 控制台DHCPCONFIG_NETINIT_DHCPCy自动获取 IPDNSCONFIG_NETDB_DNSCLIENTy域名解析TCPCONFIG_NET_TCPyTCP 协议栈UDPCONFIG_NET_UDPyUDP 协议栈ICMPCONFIG_NET_ICMP_SOCKETyPing 支持SPI FlashCONFIG_ESPRESSIF_SPIFLASHy文件系统存储PSRAMCONFIG_ESPRESSIF_SPIRAMy扩展内存10. 常见问题Q: ping 不通外网但能 ping 通网关A: 检查 DNS 配置手动设置nshechonameserver 8.8.8.8/etc/resolv.confQ: DHCP 获取不到 IPA: 检查网线连接确认路由器 DHCP 服务开启。也可以手动设置 IPnshifconfigeth0192.168.1.200 netmask255.255.255.0 nshifconfigeth0 gw192.168.1.1Q: 编译时报stdatomic.h相关错误A: 参考第 5.2 节放置兼容包装头。Q: esptool 烧录失败A: 确认 esptool 在 PATH 中确认串口号正确。按住 BOOT 按键再插 USB 可进入下载模式。11. 总结ESP32-P4 内置以太网 MAC配合 NuttX 操作系统可以快速实现有线网络功能。整个流程的关键点使用esp32p4-function-ev-board:ethernet配置启用 EMAC使用 USB 串口控制台避免外接转接器处理工具链前缀和stdatomic.h兼容性通过 DHCP 自动获取 IPDNS 解析域名ping和自定义ethdemo验证网络连通性以太网相比 WiFi 具有更低的延迟和更高的稳定性适合工业控制、网关设备等场景。ESP32-P4 NuttX 的组合为这类应用提供了良好的基础。附录ethdemo 构建文件Kconfigconfig EXAMPLES_ETHDEMO tristate Ethernet demo application default n depends on NET_TCP depends on NET_UDP if EXAMPLES_ETHDEMO config EXAMPLES_ETHDEMO_HOST string HTTP test host (IP address) default 192.168.1.1 config EXAMPLES_ETHDEMO_PORT int HTTP test port default 80 config EXAMPLES_ETHDEMO_PROGNAME string Program name default ethdemo config EXAMPLES_ETHDEMO_STACKSIZE int Stack size default DEFAULT_TASK_STACKSIZE config EXAMPLES_ETHDEMO_PRIORITY int Priority default 100 endifMakefileinclude $(APPDIR)/Make.defs PRIORITY $(CONFIG_EXAMPLES_ETHDEMO_PRIORITY) STACKSIZE $(CONFIG_EXAMPLES_ETHDEMO_STACKSIZE) PROGNAME $(CONFIG_EXAMPLES_ETHDEMO_PROGNAME) MAINSRC ethdemo_main.c include $(APPDIR)/Application.mkMake.defsifneq ($(CONFIG_EXAMPLES_ETHDEMO),) CONFIGURED_APPS $(APPDIR)/examples/ethdemo endifCMakeLists.txtif(CONFIG_EXAMPLES_ETHDEMO) nuttx_add_application( NAME ${CONFIG_EXAMPLES_ETHDEMO_PROGNAME} SRCS ethdemo_main.c STACKSIZE ${CONFIG_EXAMPLES_ETHDEMO_STACKSIZE} PRIORITY ${CONFIG_EXAMPLES_ETHDEMO_PRIORITY}) endif()
ESP32-P4 NuttX 以太网测试完整指南:从环境配置到网络验证
文章目录前言1. 硬件准备接线说明2. 开发环境概述工具链版本NuttX 源码3. 关键配置步骤3.1 Python 虚拟环境3.2 工具链前缀适配3.3 环境脚本4. 以太网 defconfig 定制4.1 原始 ethernet 配置分析4.2 修改为 USB 串口控制台4.3 添加自定义测试程序5. 编译5.1 CMake 配置5.2 处理兼容性问题5.3 编译6. 烧录7. 测试验证7.1 打开串口7.2 查看网络接口7.3 DHCP 获取 IP7.4 Ping 外网7.5 ethdemo TCP 测试8. SPI Flash 文件系统可选9. 已启用的网络功能一览10. 常见问题Q: ping 不通外网但能 ping 通网关Q: DHCP 获取不到 IPQ: 编译时报 stdatomic.h 相关错误Q: esptool 烧录失败11. 总结附录ethdemo 构建文件KconfigMakefileMake.defsCMakeLists.txt前言ESP32-P4 是乐鑫推出的高性能 RISC-V SoC内置以太网 MACEMAC支持有线网络连接。本文记录在 Windows 环境下基于 Apache NuttX 实时操作系统完成 ESP32-P4-Function-Ev-Board 以太网功能的编译、烧录和测试全过程。最终效果ESP32-P4 通过网线连接路由器自动获取 IP成功 Ping 通外网并完成 TCP 连接测试。1. 硬件准备ESP32-P4-Function-Ev-Board 1.6USB 数据线用于烧录和串口调试网线连接路由器或交换机电源USB 供电即可接线说明ESP32-P4-Function-Ev-Board 自带以太网 RJ45 接口只需插上网线即可。USB 口同时用于烧录和串口控制台USB CDC-ACM。2. 开发环境概述本文复用已有的 ESP-IDF 工具链只补齐 NuttX 编译所需的额外组件。工具链版本工具版本路径RISC-V GCC15.2.0C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204CMake4.0.3C:\Espressif\tools\cmake\4.0.3Ninja1.12.1C:\Espressif\tools\ninja\1.12.1esptool5.3.0C:\Espressif\tools\python\master\venv\ScriptsGit Bash—C:\Program Files\GitNuttX 源码cd D:\esp32p4-nuttx git clone--depth 1 https://github.com/apache/nuttx.git nuttx git clone--depth 1 https://github.com/apache/nuttx-apps.git apps3. 关键配置步骤3.1 Python 虚拟环境NuttX 的 Kconfig 解析需要kconfiglib建议单独创建 venvcd D:\esp32p4-nuttx python-m venv.venv.\.venv\Scripts\python.exe-m pip install kconfiglib14.1.03.2 工具链前缀适配NuttX CMake 期望的 RISC-V 工具链前缀是riscv64-unknown-elf-而 ESP-IDF 提供的是riscv32-esp-elf-。解决方案是创建符号链接或复制重命名# 创建工具目录mkdir D:\esp32p4-nuttx\tools\bin# 复制并重命名工具链$srcC:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\bin$dstD:\esp32p4-nuttx\tools\bin(gcc,g,ld,ar,objcopy,objdump,nm,size,strip)|ForEach-Object{Copy-Item$src\riscv32-esp-elf-$_.exe$dst\riscv64-unknown-elf-$_.exe}同时设置环境变量$env:GCC_EXEC_PREFIX C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\libexec\gcc\3.3 环境脚本创建env-esp32p4-nuttx.ps1一键加载环境$Root$PSScriptRoot$toolPaths ((Join-Path$Root.venv\Scripts),C:\Espressif\tools\python\master\venv\Scripts,(Join-Path$Roottools\bin),(Join-Path$Rootmingw64\bin),C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\bin,C:\Espressif\tools\cmake\4.0.3\bin,C:\Espressif\tools\ninja\1.12.1,C:\Program Files\Git\usr\bin,C:\Program Files\Git\bin)$existingToolPaths$toolPaths|Where-Object{Test-Path$_}$env:Path ($existingToolPaths-join;);$env:Path$env:GCC_EXEC_PREFIX C:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\libexec\gcc\Write-HostESP32-P4 NuttX environment ready at$Root4. 以太网 defconfig 定制NuttX 为 ESP32-P4-Function-Ev-Board 提供了多个预置配置。以太网功能对应的配置是esp32p4-function-ev-board:ethernet。4.1 原始 ethernet 配置分析查看nuttx\boards\risc-v\esp32p4\esp32p4-function-ev-board\configs\ethernet\defconfig关键配置项CONFIG_ESPRESSIF_EMACy # 启用以太网 MAC CONFIG_ESPRESSIF_ETH_DMA_BUFFER_SIZE512 CONFIG_NETINIT_DHCPCy # DHCP 客户端 CONFIG_NETDB_DNSCLIENTy # DNS 解析 CONFIG_NET_TCPy # TCP 协议 CONFIG_NET_UDPy # UDP 协议 CONFIG_NET_ICMP_SOCKETy # ICMP (Ping) CONFIG_SYSTEM_PINGy # ping 命令 CONFIG_UART0_SERIAL_CONSOLEy # 默认用 UART0 作控制台4.2 修改为 USB 串口控制台默认配置使用 UART0GPIO37/38作为控制台需要外接 USB-TTL 转接器。改为 USB 串口控制台后烧录和调试都用同一根 USB 线- CONFIG_UART0_SERIAL_CONSOLEy # CONFIG_ESPRESSIF_UART0 is not set CONFIG_ESPRESSIF_USBSERIALy4.3 添加自定义测试程序在apps\examples\下创建ethdemo测试应用用于验证网络连通性apps/examples/ethdemo/ethdemo_main.c#includenuttx/config.h#includestdio.h#includestring.h#includeunistd.h#includeerrno.h#includesys/socket.h#includenetinet/in.h#includearpa/inet.h#includenet/if.h#includenetutils/netlib.h#defineETHDEMO_BUF_SIZE512#defineETHDEMO_TIMEOUT5staticvoidprint_ifinfo(FARconstchar*ifname){structin_addraddr,mask,gw;uint8_tmac[IFHWADDRLEN];printf(\n Network Interface: %s \n,ifname);if(netlib_get_ipv4addr(ifname,addr)0)printf( IP Address: %s\n,inet_ntoa(addr));if(netlib_get_ipv4netmask(ifname,mask)0)printf( Netmask: %s\n,inet_ntoa(mask));if(netlib_get_dripv4addr(ifname,gw)0)printf( Gateway: %s\n,inet_ntoa(gw));if(netlib_getmacaddr(ifname,mac)0)printf( MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);}staticinttcp_connect_test(FARconstchar*host,uint16_tport){structsockaddr_inserver;structtimevaltv;intsockfd,ret;charbuf[ETHDEMO_BUF_SIZE];constchar*http_requestGET / HTTP/1.0\r\nHost: test\r\n\r\n;ssize_tnread;printf(\n TCP Connect Test \n);printf(Connecting to %s:%u...\n,host,port);sockfdsocket(AF_INET,SOCK_STREAM,0);if(sockfd0){printf(ERROR: socket() failed\n);return-errno;}tv.tv_secETHDEMO_TIMEOUT;tv.tv_usec0;setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv));setsockopt(sockfd,SOL_SOCKET,SO_SNDTIMEO,tv,sizeof(tv));memset(server,0,sizeof(server));server.sin_familyAF_INET;server.sin_porthtons(port);inet_pton(AF_INET,host,server.sin_addr);retconnect(sockfd,(structsockaddr*)server,sizeof(server));if(ret0){printf(ERROR: connect() failed\n);close(sockfd);return-errno;}printf(Connected successfully!\n);send(sockfd,http_request,strlen(http_request),0);printf(Sent HTTP request, waiting for response...\n);nreadrecv(sockfd,buf,sizeof(buf)-1,0);if(nread0){buf[nread200?200:nread]\0;printf(Received %zd bytes:\n%s\n,nread,buf);}close(sockfd);return0;}intmain(intargc,FARchar*argv[]){FARconstchar*host(argc1)?argv[1]:192.168.1.1;uint16_tport(argc2)?(uint16_t)atoi(argv[2]):80;printf(\n\n);printf( ESP32-P4 Ethernet Network Test\n);printf(\n);print_ifinfo(eth0);tcp_connect_test(host,port);printf(\n\n);printf( Test Complete\n);printf(\n);return0;}配套的构建文件Kconfig、Makefile、Make.defs、CMakeLists.txt遵循 NuttX 应用标准结构详见文末附录。在 defconfig 中启用CONFIG_EXAMPLES_ETHDEMOy CONFIG_EXAMPLES_ETHDEMO_HOST192.168.1.1 CONFIG_EXAMPLES_ETHDEMO_PORT805. 编译5.1 CMake 配置cd D:\esp32p4-nuttx..\env-esp32p4-nuttx.ps1 cmake-S nuttx-B build-ethernet-G Ninja -DCMAKE_MAKE_PROGRAMC:\Espressif\tools\ninja\1.12.1\ninja.exe-DBOARD_CONFIGesp32p4-function-ev-board:ethernet-DNUTTX_APPS_DIRD:\esp32p4-nuttx\apps-DPython3_EXECUTABLED:\esp32p4-nuttx\.venv\Scripts\python.exe-DEXTRA_FLAGS-stdgnu115.2 处理兼容性问题stdatomic.h 兼容头ESP HAL 部分代码与当前工具链的stdatomic.h不兼容需要在以下路径放置兼容包装头build-ethernet\arch\risc-v\src\common\espressif\esp-hal-3rdparty\nuttx\src\components\esp_libc\platform_include\stdatomic.h核心内容#pragmaonce#include_nextstdatomic.h#ifdefATOMIC_VAR_INIT#undefATOMIC_VAR_INIT#endif#defineATOMIC_VAR_INIT(val)(val)#ifdefatomic_init#undefatomic_init#endif#defineatomic_init(ptr,val)__atomic_store_n((ptr),(val),__ATOMIC_RELAXED)libgcc.a复制到构建目录Copy-ItemC:\Espressif\tools\riscv32-esp-elf\esp-15.2.0_20251204\riscv32-esp-elf\lib\gcc\riscv32-esp-elf\15.2.0\libgcc.a-DestinationD:\esp32p4-nuttx\build-ethernet\libgcc.a5.3 编译cmake--build build-ethernet--parallel4成功输出[1666/1666] Running utility command for nuttx_post_build esptool v5.3.0 Creating ESP32-P4 image... Successfully created ESP32-P4 image. -- Generated: nuttx.bin编译产物文件大小说明nuttx771 KBELF 可执行文件nuttx.bin339 KBESP32-P4 烧录镜像nuttx.hex812 KBIntel HEX 格式nuttx.map1.9 MB链接 Map 文件6. 烧录ESP32-P4 使用 simple boot 模式烧录地址为0x2000esptool--chip esp32p4-p COM4-b 460800write-flash-fs 4MB-fm dio-ff 80m 0x2000.\build-ethernet\nuttx.bin烧录日志Connected to ESP32-P4 on COM4 Wrote 339068 bytes at 0x00002000 Hash of data verified. Hard resetting via RTS pin...7. 测试验证7.1 打开串口python-m serial.tools.miniterm COM4 115200按 RESET 或敲回车看到nsh提示符。7.2 查看网络接口nshifconfigeth0 Link encap:Ethernet HWaddr e8:f6:0a:e3:a6:46 at RUNNING mtu1500inet addr:0.0.0.0 DRaddr:10.0.0.1 Mask:255.255.255.0此时已获取到 MAC 地址但还没有 IP。7.3 DHCP 获取 IPnshrenew eth0 nshifconfigeth0 Link encap:Ethernet HWaddr e8:f6:0a:e3:a6:46 at RUNNING mtu1500inet addr:192.168.1.135 DRaddr:192.168.1.1 Mask:255.255.255.0成功通过 DHCP 获取到 IP192.168.1.135。7.4 Ping 外网nshpingwww.baidu.com PING110.242.69.2156bytes of data56bytes from110.242.69.21:icmp_seq0time10.0ms56bytes from110.242.69.21:icmp_seq1time10.0ms56bytes from110.242.69.21:icmp_seq2time10.0ms...10packets transmitted,10received,0% packet loss,time10100ms rtt min/avg/max/mdev0.000/9.000/10.000/3.000 msDNS 解析和 ICMP 全部正常10 包 0% 丢包。7.5 ethdemo TCP 测试nshethdemoESP32-P4 Ethernet Network TestNetwork Interface: eth0IP Address:192.168.1.135 Netmask:255.255.255.0 Gateway:192.168.1.1 MAC Address: e8:f6:0a:e3:a6:46TCP Connect TestConnecting to192.168.1.1:80... Connected successfully!Sent HTTP request, waitingforresponse... Received183bytes: HTTP/1.1200OK Cache-control:no-cache, no-store, max-age0Content-Type:text/html...Test CompleteTCP 连接、HTTP 请求、数据收发全部正常。8. SPI Flash 文件系统可选首次使用 SPI Flash 需要格式化nshmksmartfs /dev/smart0 nshmount-tsmartfs /dev/smart0 /mnt nshechoHello ESP32-P4/mnt/test.txt nshcat/mnt/test.txt Hello ESP32-P49. 已启用的网络功能一览功能配置项说明以太网 MACCONFIG_ESPRESSIF_EMACy内部 EMAC 外部 PHYUSB 串口CONFIG_ESPRESSIF_USBSERIALyUSB CDC-ACM 控制台DHCPCONFIG_NETINIT_DHCPCy自动获取 IPDNSCONFIG_NETDB_DNSCLIENTy域名解析TCPCONFIG_NET_TCPyTCP 协议栈UDPCONFIG_NET_UDPyUDP 协议栈ICMPCONFIG_NET_ICMP_SOCKETyPing 支持SPI FlashCONFIG_ESPRESSIF_SPIFLASHy文件系统存储PSRAMCONFIG_ESPRESSIF_SPIRAMy扩展内存10. 常见问题Q: ping 不通外网但能 ping 通网关A: 检查 DNS 配置手动设置nshechonameserver 8.8.8.8/etc/resolv.confQ: DHCP 获取不到 IPA: 检查网线连接确认路由器 DHCP 服务开启。也可以手动设置 IPnshifconfigeth0192.168.1.200 netmask255.255.255.0 nshifconfigeth0 gw192.168.1.1Q: 编译时报stdatomic.h相关错误A: 参考第 5.2 节放置兼容包装头。Q: esptool 烧录失败A: 确认 esptool 在 PATH 中确认串口号正确。按住 BOOT 按键再插 USB 可进入下载模式。11. 总结ESP32-P4 内置以太网 MAC配合 NuttX 操作系统可以快速实现有线网络功能。整个流程的关键点使用esp32p4-function-ev-board:ethernet配置启用 EMAC使用 USB 串口控制台避免外接转接器处理工具链前缀和stdatomic.h兼容性通过 DHCP 自动获取 IPDNS 解析域名ping和自定义ethdemo验证网络连通性以太网相比 WiFi 具有更低的延迟和更高的稳定性适合工业控制、网关设备等场景。ESP32-P4 NuttX 的组合为这类应用提供了良好的基础。附录ethdemo 构建文件Kconfigconfig EXAMPLES_ETHDEMO tristate Ethernet demo application default n depends on NET_TCP depends on NET_UDP if EXAMPLES_ETHDEMO config EXAMPLES_ETHDEMO_HOST string HTTP test host (IP address) default 192.168.1.1 config EXAMPLES_ETHDEMO_PORT int HTTP test port default 80 config EXAMPLES_ETHDEMO_PROGNAME string Program name default ethdemo config EXAMPLES_ETHDEMO_STACKSIZE int Stack size default DEFAULT_TASK_STACKSIZE config EXAMPLES_ETHDEMO_PRIORITY int Priority default 100 endifMakefileinclude $(APPDIR)/Make.defs PRIORITY $(CONFIG_EXAMPLES_ETHDEMO_PRIORITY) STACKSIZE $(CONFIG_EXAMPLES_ETHDEMO_STACKSIZE) PROGNAME $(CONFIG_EXAMPLES_ETHDEMO_PROGNAME) MAINSRC ethdemo_main.c include $(APPDIR)/Application.mkMake.defsifneq ($(CONFIG_EXAMPLES_ETHDEMO),) CONFIGURED_APPS $(APPDIR)/examples/ethdemo endifCMakeLists.txtif(CONFIG_EXAMPLES_ETHDEMO) nuttx_add_application( NAME ${CONFIG_EXAMPLES_ETHDEMO_PROGNAME} SRCS ethdemo_main.c STACKSIZE ${CONFIG_EXAMPLES_ETHDEMO_STACKSIZE} PRIORITY ${CONFIG_EXAMPLES_ETHDEMO_PRIORITY}) endif()