RIOT 操作系统 Arduino Nano ESP32 板级支持详解:引脚映射、烧录流程与 STDIO 配置
2026/9/17 23:26:07 网站建设 项目流程

RIOT 操作系统 Arduino Nano ESP32 板级支持详解:引脚映射、烧录流程与 STDIO 配置

【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT

本文基于 RIOT 仓库中 Arduino Nano ESP32 的板级支持文档与源码,完整讲解该板在 RIOT 中的硬件能力、GPIO/外设默认配置表、USB Serial/JTAG 烧录流程(含下载模式手动进入方法),以及 STDIO 在 USB Serial/JTAG、tinyUSB 与 UART 三种通道间的自动选择机制。读完后,你可以在 RIOT 中正确配置该板的 ADC、PWM、SPI、I2C 与 UART 外设,独立完成固件烧录,并按需切换 STDIO 输出通道。

一、板子概述:Arduino Nano 形态的 ESP32-S3 开发板

Arduino Nano ESP32 是一块采用 Arduino Nano 板型的 ESP32-S3 开发板,其核心功能由板载的 u-Blox NORA-W106 模块提供。根据 boards/arduino-nano-esp32/doc.md 的描述,该板的主要特性包括:

  • ESP32-S3 SoC,支持 2.4 GHz WiFi 802.11b/g/n 以及 Bluetooth 5 / BLE
  • 8 MByte 嵌入式 QSPI RAM(PSRAM)
  • 16 MByte Flash
  • 带独立红、绿、蓝三色 LED 的 RGB 指示灯
  • 原生 USB 接口与 USB Serial/JTAG 接口

在 RIOT 中,该板对应的 CPU 型号为esp32s3r8,即带 8 MB QSPI PSRAM 的 ESP32-S3 变体。这一点在 boards/arduino-nano-esp32/Makefile.features 中有明确定义:

# the board uses a ESP32-S3 with embedded 8MB QSPI PSRAM and a 16MB QSPI Flash CPU_MODEL = esp32s3r8 # common board and CPU features include $(RIOTBOARD)/common/esp32s3/Makefile.features

同时,boards/arduino-nano-esp32/Kconfig 中的BOARD_ARDUINO_NANO_ESP32选项会自动选择BOARD_COMMON_ESP32S3CPU_MODEL_ESP32S3_R8,保证了 Kconfig 体系下的默认 CPU 型号与 Make 系统一致。

板级提供的功能特性

从 boards/arduino-nano-esp32/Makefile.features 可以看到,RIOT 为该板声明了如下功能特性:

# peripherals provided by the board FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_pwm FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_usbdev # other features provided by the board FEATURES_PROVIDED += arduino_analog FEATURES_PROVIDED += arduino_i2c FEATURES_PROVIDED += arduino_pins FEATURES_PROVIDED += arduino_pwm FEATURES_PROVIDED += arduino_spi FEATURES_PROVIDED += arduino_uart FEATURES_PROVIDED += esp_jtag FEATURES_PROVIDED += highlevel_stdio FEATURES_PROVIDED += tinyusb_device

这些特性可以分成三类:

  1. 标准外设接口periph_adcperiph_i2cperiph_pwmperiph_spiperiph_usbdev,对应 RIOT 的统一外设抽象层;
  2. Arduino 引脚兼容层arduino_analogarduino_i2carduino_pinsarduino_pwmarduino_spiarduino_uart,使板级引脚可以按 Arduino 命名习惯使用,映射关系定义在 boards/arduino-nano-esp32/include/arduino_iomap.h;
  3. USB 相关能力esp_jtag(USB Serial/JTAG 接口,即烧录与默认 STDIO 通道)、highlevel_stdio(高级 STDIO 抽象)、tinyusb_device(TinyUSB 设备栈支持)。

二、硬件与板级配置:默认引脚功能分配

2.1 MCU 与板级说明

文档中关于 MCU 的说明指出:该板的大部分功能由 ESP32-S3 SoC 提供,关于 ESP32-S3 SoC 家族(ESP32x SoC)的更详细信息应参阅 RIOT 文档中的 "ESP32 SoC Series" 章节。

板级硬件方面,Arduino Nano ESP32 除了 RGB 指示灯(红、绿、蓝各为独立 LED)之外没有其他特殊板载外设,因此板级配置的重心就是外设与 GPIO 的默认分配。文档给出的配置概览为:

  • 8 路 ADC 通道(若启用periph_i2c模块,则为 4 路)
  • 1 路 SPI
  • 1 路 I2C
  • 1 路 UART
  • 2 路 PWM 设备(PWM_DEV(0) 含 4 个通道,PWM_DEV(1) 含 3 个 RGB LED 通道)

2.2 默认引脚配置表

文档给出了按 GPIO 功能分类的默认板级配置表(该表可被应用特定的板级配置覆盖):

功能GPIO备注
ADC_LINE(0)GPIO1
ADC_LINE(1)GPIO2
ADC_LINE(2)GPIO3
ADC_LINE(3)GPIO4
ADC_LINE(4)GPIO11若使用periph_i2c则不可用
ADC_LINE(5)GPIO12若使用periph_i2c则不可用
ADC_LINE(6)GPIO13
ADC_LINE(7)GPIO14
PWM_DEV(0):0GPIO6
PWM_DEV(0):1GPIO8
PWM_DEV(0):2GPIO9
PWM_DEV(0):3GPIO18
PWM_DEV(1):0GPIO46红色 LED
PWM_DEV(1):1GPIO0绿色 LED
PWM_DEV(1):2GPIO45蓝色 LED
I2C_DEV(0):SCLGPIO12
I2C_DEV(0):SDAGPIO11
SPI_DEV(0):CLKGPIO48使用 SPI2_HOST(FSPI)
SPI_DEV(0):MISOGPIO47使用 SPI2_HOST(FSPI)
SPI_DEV(0):MOSIGPIO38使用 SPI2_HOST(FSPI)
SPI_DEV(0):CS0GPIO21使用 SPI2_HOST(FSPI)
UART_DEV(0):TxDGPIO43控制台(固定)
UART_DEV(0):RxDGPIO44控制台(固定)

2.3 源码印证:periph_conf.h 中的实际定义

上述配置表在 boards/arduino-nano-esp32/include/periph_conf.h 中逐项落地,几个值得注意的实现细节:

ADC 通道与 I2C 的条件互斥。文档表中"若使用periph_i2c则不可用"的备注,在源码中通过宏条件直接实现:

#ifndef ADC_GPIOS # if !MODULE_PERIPH_I2C # define ADC_GPIOS { GPIO1, GPIO2, GPIO3, GPIO4, GPIO11, GPIO12, GPIO13, GPIO14 } # else /* !MODULE_PERIPH_I2C */ # define ADC_GPIOS { GPIO1, GPIO2, GPIO3, GPIO4 } # endif /* !MODULE_PERIPH_I2C */ #endif

原因是 GPIO11/GPIO12 已分配给 I2C_DEV(0) 的 SDA/SCL 信号,为避免资源冲突,启用periph_i2c时仅保留连接 ADC1 的 4 路通道。源码注释还特别提示:GPIO3 在EFUSE_STRAP_JTAG_SEL置位时是 strapping 引脚,使用 ADC 时需要注意。

I2C 接口。I2C_DEV(0) 的 SCL/SDA 分别固定为 GPIO12/GPIO11,默认总线速度为快速模式:

#ifndef I2C0_SPEED # define I2C0_SPEED I2C_SPEED_FAST /**< I2C bus speed of I2C_DEV(0) */ #endif #ifndef I2C0_SCL # define I2C0_SCL GPIO12 /**< SCL signal of I2C_DEV(0) */ #endif #ifndef I2C0_SDA # define I2C0_SDA GPIO11 /**< SDA signal of I2C_DEV(0) */ #endif

PWM 设备。两个 PWM 设备的通道分配如下:PWM_DEV(0) 使用经典 Arduino 数字引脚 D3、D5、D6、D9(对应 GPIO6、GPIO8、GPIO9、GPIO18)中未分配给 SPI 的引脚;PWM_DEV(1) 则专门承载 RGB 指示灯:

#ifndef PWM0_GPIOS # define PWM0_GPIOS { GPIO6, GPIO8, GPIO9, GPIO18 } #endif #ifndef PWM1_GPIOS # define PWM1_GPIOS { GPIO46, GPIO0, GPIO45 } #endif

对应关系为:PWM1:0 红色 LED(GPIO46)、PWM1:1 绿色 LED(GPIO0)、PWM1:2 蓝色 LED(GPIO45)。

SPI 接口走 GPIO 矩阵。SPI_DEV(0) 使用 FSPI(SPI2_HOST)外设,四个信号线通过 GPIO 矩阵从普通 I/O 引脚路由到 FSPI 的对应信号:

#ifndef SPI0_CTRL # define SPI0_CTRL FSPI /**< FSPI is used as SPI_DEV(0) */ #endif #ifndef SPI0_SCK # define SPI0_SCK GPIO48 /**< Routed vio the GPIO matrix to FSPI CLK signal */ #endif #ifndef SPI0_MISO # define SPI0_MISO GPIO47 /**< Routed vio the GPIO matrix to FSPI MISO signal */ #endif #ifndef SPI0_MOSI # define SPI0_MOSI GPIO38 /**< Routed vio the GPIO matrix to FSPI MOSI signal */ #endif #ifndef SPI0_CS0 # define SPI0_CS0 GPIO21 /**< Routed vio the GPIO matrix to FSPI CS0 signal */ #endif

UART 固定分配。ESP32-S3 最多提供 3 路 UART,但板上只配置了 UART_DEV(0),且 TxD/RxD 为固定直连 I/O 引脚,不可更改:

#define UART0_TXD GPIO43 /**< direct I/O pin for UART_DEV(0) TxD, can't be changed */ #define UART0_RXD GPIO44 /**< direct I/O pin for UART_DEV(0) RxD, can't be changed */

此外,该文件所有#ifndef保护都意味着:应用侧可以通过"应用特定板级配置"覆盖任意默认值,这是 ESP32 板族统一的定制机制。

2.4 板载 LED 定义与 SAUL 设备

boards/arduino-nano-esp32/include/board.h 定义了三个板载 LED,均为低电平有效

#define LED0_PIN GPIO46 /**< LED0 pin (red) */ #define LED0_ACTIVE (0) /**< LED0 is low active */ #define LED1_PIN GPIO0 /**< LED1 pin (green) */ #define LED1_ACTIVE (0) /**< LED1 is low active */ #define LED2_PIN GPIO45 /**< LED2 pin (blue) */ #define LED2_ACTIVE (0) /**< LED2 is low active */

并进一步别名为LED_RED_PINLED_GREEN_PINLED_BLUE_PIN,方便按颜色引用。

这些 LED 同时被注册为 SAUL GPIO 设备。boards/arduino-nano-esp32/include/gpio_params.h 中的saul_gpio_params数组为三路 LED 配置了GPIO_OUT模式与SAUL_GPIO_INVERTED标志,从而自动处理低电平有效的极性反转:

static const saul_gpio_params_t saul_gpio_params[] = { { .name = "LED red", .pin = LED0_PIN, .mode = GPIO_OUT, .flags = SAUL_GPIO_INVERTED, }, ... };

而 boards/arduino-nano-esp32/Makefile.dep 中可以看到,当应用启用了saul_default模块时会自动引入saul_gpio模块,使上述 SAUL GPIO 设备生效;同时该板无条件依赖 ESP32-S3 的公共板级模块:

ifneq (,$(filter saul_default,$(USEMODULE))) USEMODULE += saul_gpio endif USEMODULE += boards_common_esp32s3 include $(RIOTBOARD)/common/esp32s3/stdio_esp32s3_default.dep.mk

三、烧录流程:USB Serial/JTAG 与外部串口适配器

3.1 通过 USB Serial/JTAG 接口烧录(推荐)

该板没有板载 USB-to-Serial 芯片,最方便的烧录方式就是直接使用芯片自带的 USB Serial/JTAG 接口:将板子通过 USB 连接到宿主机,然后执行:

BOARD=arduino-nano-esp32 make flash ...

需要留意一个常见故障:RIOT 的 make 系统通常会在烧录前自动复位板子以启用 USB Serial/JTAG 接口。某些特殊情况下自动复位不生效,烧录程序无法连接板子,最终报超时错误:

Serial port /dev/ttyACM0 Connecting... ... serial.serialutil.SerialTimeoutException: Write timeout

文档指出,这种情况例如发生在板子尚未烧录过 RIOT 固件、或 USB 接口正被其他用途占用时。解决方法是手动进入下载模式:按住 RESET 按键的同时拉低 GPIO0(B1)引脚,然后释放 RESET 按键。进入下载模式后,USB Serial/JTAG 接口始终可用。

3.2 使用外部 USB-to-Serial 适配器烧录

也可以使用外部 USB-to-Serial 适配器。适配器需接到 UART0 的 TxD(GPIO43)与 RxD(GPIO44)。烧录前同样需要先进入下载模式:按住 RESET 按键的同时拉低 GPIO0(B1)引脚。进入下载模式后执行相同命令:

BOARD=arduino-nano-esp32 make flash ...

文档同时提示:关于 ESP32-S3 的更多细节以及如何为 ESP32-S3 板配置和编译 RIOT,应参阅 RIOT 文档中的esp32_riot相关章节。

四、STDIO 配置:三种通道的自动选择机制

4.1 默认行为:USB Serial/JTAG 作为 STDIO 通道

由于板上没有 USB-to-Serial 芯片,RIOT 默认使用 USB Serial/JTAG 接口作为 STDIO 通道,对应模块为stdio_usb_serial_jtag,其对外提供 USB CDC ACM 接口。

4.2 与 USB 设备栈的联动

文档说明:如果 USB 端口被 USBUS 协议栈或 TinyUSB 协议栈占用,则 STDIO 会隐式改用stdio_cdc_acmstdio_tinyusb_cdc_acm模块,仍然经由 USB CDC ACM 接口输出。

这一隐式选择逻辑在 boards/common/esp32s3/stdio_esp32s3_default.dep.mk 中实现(该文件被板级Makefile.dep引入):

ifneq (,$(filter stdio_default,$(USEMODULE))) ifneq (,$(filter usbus,$(USEMODULE))) USEMODULE += stdio_cdc_acm FEATURES_REQUIRED += highlevel_stdio else ifneq (,$(filter tinyusb_device,$(USEMODULE))) USEMODULE += stdio_tinyusb_cdc_acm FEATURES_REQUIRED += highlevel_stdio else # Use stdio_usb_serial_jtag if no other stdio is requested explicitly # and neither USBUS nor tinyusb_device are used USEMODULE += stdio_usb_serial_jtag endif # Even if only stdio_usb_serial_jtag is enabled, usb_board_reset is enabled # since there should be a CDC ACM interface in any case. This is necessary, # for example, to reset the board if stdio_cdc_acm or stdio_tinyusb_cdc_acm # was previously used. USEMODULE += usb_board_reset include $(RIOTMAKE)/tools/usb_board_reset.mk endif

从源码结构看,这段依赖脚本还有一层实用考量:即使最终只启用了stdio_usb_serial_jtag,系统也会同时启用usb_board_reset模块。这是因为板上始终应存在一个 CDC ACM 接口,这样当之前烧录的固件使用的是stdio_cdc_acmstdio_tinyusb_cdc_acm时,新固件仍能通过 USB 将板子复位完成更新。

4.3 使用 UART + 外部串口适配器作为 STDIO

如果需要改用 UART 输出(例如配合外部 USB-to-Serial 适配器调试),只需在模块列表中显式加入stdio_uart

BOARD=arduino-nano-esp32 USEMODULE=stdio_uart make flash ...

此时控制台将走 UART_DEV(0),即固定连接到 GPIO43(TxD)与 GPIO44(RxD)。

五、小结与快速上手

  • 板级标识BOARD=arduino-nano-esp32,CPU 型号esp32s3r8(8 MB QSPI PSRAM + 16 MB Flash),定义于 boards/arduino-nano-esp32/Makefile.features 与 boards/arduino-nano-esp32/Kconfig;
  • 引脚配置:8 路 ADC(启用 I2C 后为 4 路)、1 路 SPI(FSPI,经 GPIO 矩阵路由)、1 路 I2C(GPIO11/GPIO12,快速模式)、1 路固定 UART(GPIO43/GPIO44)、2 组共 7 路 PWM(含 RGB LED),全部可在 boards/arduino-nano-esp32/include/periph_conf.h 中核对,并支持应用侧覆盖;
  • LED:红/绿/蓝三路独立 LED(GPIO46/GPIO0/GPIO45),低电平有效,且注册为带极性反转的 SAUL GPIO 设备,见 boards/arduino-nano-esp32/include/board.h 与 boards/arduino-nano-esp32/include/gpio_params.h;
  • 烧录:默认走 USB Serial/JTAG(BOARD=arduino-nano-esp32 make flash ...);若自动复位失败导致SerialTimeoutException,按住 RESET 同时拉低 GPIO0(B1)手动进入下载模式;也可用外部 USB-to-Serial 适配器接 GPIO43/GPIO44 烧录;
  • STDIO:默认stdio_usb_serial_jtag;启用usbus时自动切换为stdio_cdc_acm,启用tinyusb_device时自动切换为stdio_tinyusb_cdc_acm;显式USEMODULE=stdio_uart可改用 UART 控制台,选择逻辑见 boards/common/esp32s3/stdio_esp32s3_default.dep.mk。

以上配置均以当前仓库中的板级支持代码为准;如需为特定应用修改默认引脚分配,可按文档所述的 ESP32 "application-specific configurations" 机制在应用侧覆盖periph_conf.h中的相关宏定义。

【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询