ESP32-S31 是乐鑫 2026 年量产的新一代 SoC,与 ESP32-S3 相比是一次架构换代(Xtensa LX7 换成了 RISC-V),无线与有线连接能力也全面升级。本文记录这块板子的开箱过程、基于 ESP-IDF v6.1 的开发环境搭建(含几个踩坑记录),以及第一个工程——板载 RGB LED 的循环点亮测试,供同样拿到这块板子的朋友参考。
一、开箱展示
包裹采用防静电袋加泡棉缓冲,运输过程中板卡完好。



二、开发板信息
ESP32-S31-Function-CoreBoard-1 是乐鑫官方推出的、面向联网 AIoT 原型验证的功能核心板,搭载 ESP32-S31-WROOM-3 模组,在保持无线连接能力的同时,强化了有线连接与音频特性。
| 核心模组 | ESP32-S31-WROOM-3,双核 32-bit RISC-V,主频 320 MHz,其中一核支持 128-bit 数据通路与 SIMD 指令 |
| 无线连接 | Wi-Fi 6(802.11ax)、BLE 5.4(含 LE Audio)、经典蓝牙 BR/EDR、IEEE 802.15.4(Zigbee/Thread/Matter) |
| 有线连接 | RJ45 千兆以太网,10/100/1000 Mbps 自适应 |
| USB 接口 | USB 2.0 Type-A 主机口(可对外提供 500 mA)、USB Type-C(Serial/JTAG,烧录调试用)、USB Type-C 转 UART |
| 音频能力 | 板载麦克风,ES8311 音频编解码 + NS4150B D 类功放,可驱动 4 Ω / 3 W 扬声器 |
| 扩展与调试 | 40 针 J2 排针引出全部 GPIO;板载可寻址 RGB LED(GPIO60);RST / BOOT 按键;J5 排针可测量模组功耗 |
芯片内部资源:512 KB HP SRAM + 32 KB LP SRAM,支持外接 250 MHz 8-bit DDR PSRAM,60 个 GPIO,内置 JPEG 编解码器、像素处理加速器(PPA)、2D-DMA,以及 14 路电容触摸。
资源分布
Type-C 调试接口与 UART 接口;
RGB LED:可寻址发光二极管,由 GPIO60 驱动;
RJ45 以太网接口;
USB 2.0 Type-A 接口,连接芯片 USB 2.0 OTG High-Speed;
RST 复位按键、BOOT 按键;
板载麦克风与扬声器输出接口。


原理图


三、开发环境搭建
这部分是本文最想分享的内容。ESP32-S31 太新,中文资料几乎没有,搭建过程我是照着报错一个个摸过来的,几个坑记录如下。
环境:Windows 11 + VS Code + ESP-IDF 扩展 v2.2.0。


3.1 扩展报 eim_idf.json doesn't exists
装好 ESP-IDF 扩展后,执行 ESP-IDF: Open ESP-IDF Installation Manager 直接报错。翻扩展日志(esp_idf_vsc_ext.log)找到根因:
C:\Espressif\tools\eim_idf.json doesn't exists.
原因:扩展本身不包含 ESP-IDF,它依赖独立的 EIM(Espressif Installation Manager)工具完成框架安装。报错不是配置错了,是 EIM 还没装。
3.2 winget 包名与文档不一致
按官方文档执行 winget install Espressif.EIM,先看一下仓库里实际有什么:
PS> winget search Espressif
名称 ID 版本 源
--------------------------------------------------------------------
ESP-IDF Installation Manager CLI Espressif.EIM-CLI 0.19.0 winget
eim Espressif.eim 0.19.0 winget
并没有 Espressif.EIM 这个 ID。winget 匹配不区分大小写,因此上面那条命令实际安装的是 Espressif.eim(GUI 版 0.19.0),安装在 C:\Program Files\eim\——能装上,但过程容易让人困惑。
3.3 EIM 装上了,eim 命令却找不到
装完后终端执行 eim 提示不是可识别的命令。用完整路径执行 eim.exe --version 才看到真相:
Failed to add eim to PATH: Failed to update registry PATH: Registry PATH update failed:
eim 0.19.0
EIM 已经安装成功,但它把自己写入 PATH 时更新注册表失败了,程序本体在 C:\Program Files\eim\eim.exe,只是终端里找不到。
临时解法(当前窗口生效):
$env:Path += ";C:\Program Files\eim"
永久解法(重开终端生效):
[Environment]::SetEnvironmentVariable("Path",
[Environment]::GetEnvironmentVariable("Path","User") + ";C:\Program Files\eim", "User")
3.4 安装 ESP-IDF v6.1
这一步对 S31 来说最关键:ESP32-S31 目前仅在 ESP-IDF v6.1(preview 支持)及 master 分支获得支持,v6.0 及更早版本无法选择 esp32s31 目标。


因此不能用默认的"最新稳定版",要显式指定版本(命令行或GUI安装向导):
eim install -i v6.1
EIM 会自动完成 IDF 源码、xtensa / riscv 编译器、CMake、Ninja、OpenOCD、Python 虚拟环境的下载与配置(默认走乐鑫国内镜像,速度不错)。完成后布局如下:
| ESP-IDF 源码 | C:\esp\v6.1\esp-idf |
| 工具链 | C:\Espressif\tools |
| Python 虚拟环境 | C:\Espressif\tools\python\v6.1\venv |
| 版本清单 | C:\Espressif\tools\eim_idf.json |
回到 VS Code,执行 ESP-IDF: Select Current ESP-IDF Version 选中 v6.1,再执行 ESP-IDF: Doctor Command 做环境体检。
3.5 关于 IntelliSense 报错
工程首次构建前,VS Code 的 C/C++ IntelliSense 会报大量"无法打开源文件"错误,这是正常现象:sdkconfig.h 与 compile_commands.json 都要等首次构建才会生成。建议在工程 .vscode/settings.json 中加入:
"C_Cpp.intelliSenseEngine": "disabled"
关掉 cpptools 的 IntelliSense(ESP-IDF 扩展自带 esp-clangd,基于编译数据库提供补全,两者并存会互相报错),编译一次后提示即消失。
四、工程测试:RGB LED 循环点亮
板载 LED 的一个细节
查原理图之前我先按传统思路写了电平翻转点灯,结果灯给我表演了个常亮青色:数据线上一堆乱码时序,WS2812 把闩锁到的垃圾位原样点了出来,颜色完全随机。这也从侧面印证了它是可寻址灯珠——普通 LED 根本不可能被"点"出颜色来。翻 ESP-IDF 的 blink 示例配置才注意到,sdkconfig.defaults.esp32s31 的注释里写得明明白白:
# ESP32-S31 function core board uses GPIO60 for the on-board LED
# ESP32-S31 Korvo board uses GPIO37 for the on-board LED
且这块板的板载 LED 是可寻址 RGB 发光二极管(WS2812 类),不是普通 LED——电平翻转是点不亮的,必须走 led_strip 组件的 RMT 后端。


Flash 容量的一个小坑
新建工程不指定的话默认按 2 MB Flash 编译,而这块板实际是 16 MB——首次运行串口里会出现这条告警:
W (403) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k).
芯片信息里 Flash 也只显示 2 MB。解法:在 sdkconfig.defaults 里加一行 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y,把工程根目录的 sdkconfig 删掉再重新编译(或执行 idf.py reconfigure),默认值会重新套用。
工程结构
esp32s31/
├── CMakeLists.txt
├── sdkconfig.defaults # GPIO60、周期 1000 ms、Flash 16MB
└── main/
├── CMakeLists.txt
├── idf_component.yml # 依赖 espressif/led_strip ^3.0.0
├── Kconfig.projbuild # BLINK_GPIO / BLINK_PERIOD
└── blink.c
代码
上电先打印一份芯片信息(这也是测评的实测素材),随后初始化 led_strip 并做颜色循环:
static void print_chip_info(void)
{
esp_chip_info_t chip;
esp_chip_info(&chip);
uint32_t flash_size = 0;
esp_flash_get_size(NULL, &flash_size);
uint8_t mac[6] = {0};
esp_read_mac(mac, ESP_MAC_WIFI_STA);
printf("IDF version : %s\n", esp_get_idf_version());
printf("Target : %s\n", CONFIG_IDF_TARGET);
printf("CPU cores : %d\n", chip.cores);
printf("CPU freq : %d MHz\n", CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ);
printf("Flash : %u MB\n", (unsigned)(flash_size / (1024 * 1024)));
printf("Free heap : %u bytes\n", (unsigned)esp_get_free_heap_size());
printf("Wireless : ");
if (chip.features & CHIP_FEATURE_WIFI_BGN) printf("2.4GHz-WiFi6 ");
if (chip.features & CHIP_FEATURE_BLE) printf("BLE5.4 ");
if (chip.features & CHIP_FEATURE_BT) printf("BT-Classic ");
if (chip.features & CHIP_FEATURE_IEEE802154) printf("802.15.4 ");
printf("\n");
}
static led_strip_handle_t s_led_strip;
static void configure_led(void)
{
led_strip_config_t strip_config = {
.strip_gpio_num = BLINK_GPIO, /* GPIO60 */
.max_leds = 1,
};
led_strip_rmt_config_t rmt_config = {
.resolution_hz = 10 * 1000 * 1000,
.flags.with_dma = false,
};
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &s_led_strip));
led_strip_clear(s_led_strip);
}
void app_main(void)
{
print_chip_info();
configure_led();
/* 红-绿-蓝-黄-青-品红 循环,亮度 64/255 */
size_t idx = 0;
while (1) {
const rgb_color_t *c = &s_colors[idx];
led_strip_set_pixel(s_led_strip, 0, c->r, c->g, c->b);
led_strip_refresh(s_led_strip);
idx = (idx + 1) % COLOR_COUNT;
vTaskDelay(pdMS_TO_TICKS(BLINK_PERIOD));
}
}
效果
烧录过程如下,esptool 依次写入 bootloader、分区表和应用镜像,两次 Flash Done(注意命令行里的 --flash_size 16MB,正是上一节那个坑修好后的效果):


上电后串口会打印一份芯片信息,实测输出如下(Free heap 每次上电会有小幅浮动,就不贴具体数值了):
============ ESP32-S31 chip info ============
IDF version : v6.1
Target : esp32s31
CPU cores : 2
CPU freq : 320 MHz
Flash : 16 MB (external)
Wireless : 2.4GHz-WiFi6 BLE5.4 802.15.4
=============================================
一个实测细节:Wireless 一行里没有 BT-Classic 位。S31 规格上支持经典蓝牙 BR/EDR,但 v6.1 还处于 preview 支持阶段,esp_chip_info 尚未把这个 bit 置上,串口里看不到,属于正常现象。
RGB LED 以 1 s 周期按红、绿、蓝、黄、青、品红循环;


串口同步打印当前颜色序号与 RGB 值。
五、总结
本文介绍了 ESP32-S31-Function-CoreBoard-1 开发板的开箱、资源分布与硬件特性,记录了基于 EIM 搭建 ESP-IDF v6.1 环境的完整过程(含 eim_idf.json 报错、winget 包名、PATH 注册表更新失败、v6.1 版本选择四个问题的定位与解决),最后通过 led_strip 组件实现了板载 RGB LED 的循环点亮,为后续开发提供了参考。
几点体会:
S31 的规格确实是越级的。Wi-Fi 6、千兆以太网、经典蓝牙 BR/EDR 三样凑齐,做多协议网关不再需要外挂芯片,这是相对 S3 的质变。
preview 支持要有心理准备。v6.1 里 S31 处于预览状态,外设驱动未必齐全,做产品建议跟 master 分支。
新芯片最大的成本不在写代码,在环境
我要赚赏金
