Zephyr 上的 ESP32 SoC 特性解析与 AMP 非对称多处理实践
【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr
ESP32 是乐鑫(Espressif)推出的集成 Wi-Fi 与双模蓝牙的 Xtensa 双核 SoC,也是 Zephyr 中支持最完善的平台之一。本文以 boards/espressif/common/soc-esp32-features.rst 为主线,系统梳理 ESP32 在 Zephyr 下的硬件特性清单、双核 AMP(非对称多处理)运行机制、相关 Kconfig 与源码实现,并结合构建烧录流程给出可落地的开发方案。读完本文,你将掌握如何在 Zephyr 中为 ESP32 双核分别构建独立应用、通过 OpenAMP 交换数据,以及理解 APPCPU 串口输出的限制与规避方法。
ESP32 硬件特性总览
根据 soc-esp32-features.rst,ESP32 在 Zephyr 中对外暴露的 SoC 级特性可归纳为五大类:
处理器与存储
- 双核 Xtensa LX6 微处理器,主频 160 MHz 或 240 MHz;
- 520 KB 片上 SRAM(Zephyr 中实际可配置用于内核堆的 RAM 以板级 yaml 为准,例如 ESP32-DevKitC 的
ram: 8192KB 口径包含 PSRAM 扩展); - 支持单核与双核两种变体。
无线连接
- Wi-Fi 802.11 b/g/n/e/i;
- 蓝牙 v4.2 BR/EDR 与 BLE。
在 Zephyr 的设备树中,这两个能力通过 esp32_devkitc_procpu.dts 中的节点显式启用:
&esp32_bt_hci { status = "okay"; }; &wifi { status = "okay"; };同时chosen中通过zephyr,bt-hci = &esp32_bt_hci;将蓝牙 HCI 指定为 ESP32 内置控制器,应用层可直接使用 Zephyr 蓝牙协议栈。
外设接口
原文档列出的外设矩阵如下:
| 外设类别 | 数量/规格 |
|---|---|
| 12-bit ADC | 最多 18 通道 |
| 8-bit DAC | 2 路 |
| 触摸传感器 | 10 路 |
| SPI | 4 路 |
| I2S | 2 路 |
| I2C | 2 路 |
| UART | 3 路 |
| SD/SDIO/MMC | 主机接口 |
| SDIO/SPI | 从机(Slave)接口 |
| Ethernet | MAC |
| CAN bus | 2.0 |
| IR | RX/TX |
| Motor PWM | 支持 |
| LED PWM | 最多 16 通道 |
| 传感器 | Hall effect(霍尔效应)、温度传感器 |
这些外设并非只是纸面规格,Zephyr 中已有对应驱动并在板级设备树中完成 pinmux 与使能配置。例如 esp32_devkitc_procpu.dts 中:
&i2c0 { status = "okay"; clock-frequency = <I2C_BITRATE_STANDARD>; sda-gpios = <&gpio0 21 GPIO_OPEN_DRAIN>; scl-gpios = <&gpio0 22 GPIO_OPEN_DRAIN>; pinctrl-0 = <&i2c0_default>; pinctrl-names = "default"; };- I2C0 工作于标准模式(100 kHz),SDA/SCL 复用 GPIO21/GPIO22;
- SPI2/SPI3、UART0/1/2、I2S0/1、touch、trng 等在板级均给出默认使能与 pinctrl 配置;
gpio-reserved-ranges用于屏蔽与 flash/PSRAM 复用的 GPIO,避免被普通 GPIO 应用误用。
板级 yaml(esp32_devkitc_procpu.yaml)进一步声明了 Zephyr 对该 SoC 已支持的特性集合:adc、dac、gpio、i2c、i2s、watchdog、uart、nvs、pwm、spi、counter、entropy、input、crypto、retained_mem、netif:wifi、pulse_io,开发者在prj.conf中按需开启对应驱动 Kconfig 即可。
密码学硬件加速
ESP32 内置加密硬件加速单元,支持:
- RNG(真随机数发生器)
- ECC(椭圆曲线密码)
- RSA
- SHA-2
- AES
在 Zephyr 中对应crypto驱动与entropy驱动(esp32_devkitc_procpu.dts 中&trng0 { status = "okay"; };即为熵源节点),可支撑安全启动、TLS、固件加密等安全场景。
低功耗
- 深度睡眠电流低至 5 µA,配合 Zephyr 电源管理(
soc/espressif/common下的power.c、poweroff.c、pmstats.c)与retained_mem保留内存机制,可设计电池供电的低功耗节点。
非对称多处理(AMP)机制
原文档指出:搭载 ESP32 与 ESP32-S3 的板卡支持同时运行两个独立应用。利用双核架构,每个核可以独立启动执行自定义任务,也可以通过OpenAMP 框架交换数据。Zephyr 的ipc示例分类(:zephyr:code-sample-category:ipc`)即提供 OpenAMP 相关的参考实现。
AMP 模式下两个核的分工如下:
- PROCPU(Core 0):运行 Zephyr 主应用,负责系统初始化、外设管理与通信;
- APPCPU(Core 1):运行独立的第二个应用镜像,通过 OpenAMP RPMsg 与 PROCPU 交互。
从仓库结构可以印证这一设计:以 ESP32-DevKitC 为例,boards/espressif/esp32_devkitc 目录同时提供 procpu 与 appcpu 两套板级定义:
- esp32_devkitc_procpu.dts / esp32_devkitc_procpu.yaml /
esp32_devkitc_procpu_defconfig - esp32_devkitc_appcpu.dts / esp32_devkitc_appcpu.yaml /
esp32_devkitc_appcpu_defconfig - 分区表使用
espressif/partitions_0x1000_amp.dtsi,为两个核分别划分 slot 分区。
从 esp32_devkitc_appcpu.yaml 的testing.ignore_tags可以看出,APPCPU 镜像主要面向 IPC 类测试,网络、蓝牙、flash、内核等大块功能被显式排除——这正是 AMP 场景下“每个核执行独立定制任务”的体现。
AMP 使能条件与内存配置
AMP 能力由 soc/espressif/common/Kconfig.amp 控制,关键约束如下:
config SOC_ENABLE_APPCPU bool default y depends on (IPM || MBOX) depends on SOC_SERIES_ESP32 || SOC_SERIES_ESP32S3- 只有启用IPM(处理器间消息)或 MBOX时,PROCPU 才会映射并启动 APPCPU;
- 仅ESP32 与 ESP32-S3两个系列支持(ESP32-C 系列为单核,不在此列);
SOC_ESP32_APPCPU_TARGET标记当前构建目标是双核 SoC 的 APPCPU(Core 1)镜像。
当SOC_ENABLE_APPCPU开启后,可配置 APPCPU 的独立内存区域大小(默认值):
| 配置项 | 含义 | 默认值 |
|---|---|---|
ESP_APPCPU_IRAM_SIZE | APPCPU 指令 RAM | 0x10000(64 KB) |
ESP_APPCPU_DRAM_SIZE | APPCPU 数据 RAM | 0x10000(64 KB) |
ESP_APPCPU_IROM_SIZE | APPCPU 指令 ROM(flash 映射) | 0x100000(1 MB) |
ESP_APPCPU_DROM_SIZE | APPCPU 数据 ROM(flash 映射) | 0x100000(1 MB) |
这些区域由soc/espressif/esp32/default_appcpu.ld链接脚本承载,用于将 APPCPU 镜像的代码段与数据段固定到独立地址空间。
AMP 的源码级实现
AMP 启动链路位于 soc/espressif/esp32/esp32-mp.c,核心函数包括:
esp_appcpu_init():通过SYS_INIT(esp_appcpu_init, POST_KERNEL, ...)在内核启动后期自动执行(非 MCUboot 场景),从slot0_appcpu_partition分区读取 APPCPU 镜像;esp_appcpu_image_load(hdr_offset, &entry_addr):用 bootloader 的 mmap 接口读取 flash 中的 APPCPU 镜像,校验 IRAM/DRAM 目标地址与入口点合法性后,把 IRAM、DRAM 段搬运到目标内存;esp_appcpu_start2(entry_point):解暂停(unstall)APPCPU、使能时钟门控、复位 APPCPU 并设置启动地址;esp_appcpu_image_stop()/esp_appcpu_image_start(hdr_offset):分别用于暂停与启动 APPCPU 镜像,started静态标志保证 APPCPU 只启动一次。
值得注意的是,源码注释明确提示:启动序列中的串口输出(ets_printf/ ROM 字符发送)对启动可靠性是必须的——即使是用k_busy_wait()精确复刻时序,某些板卡仍会出现 APPCPU 无法启动的偶发挂起,因此该段日志被刻意保留。
AMP 串口输出限制(重要)
原文档特别提示:
在当前的 Zephyr ESP32 实现中,运行于 APPCPU 的应用尚不能访问由 Zephyr 管理的串口驱动(如
printk()、日志系统或 console UART),串口输出 API 仅在 PROCPU 可用。
作为规避方案,APPCPU 上的应用可以使用ESP32 ROM 函数ets_printf()输出诊断或调试信息。这一约束也被 esp32-mp.c 印证:APPCPU 启动序列全程使用ets_printf()与esp_rom_output_tx_one_char()而非 Zephyr 的printk()。设计 AMP 应用时,应将日志输出集中在 PROCPU,APPCPU 仅承担计算/实时任务并通过 OpenAMP 将结果回传。
构建、烧录与运行实践
虽然特性文档本身不展开构建细节,但 AMP/IPC 开发离不开烧录流程,此处结合 boards/espressif/common/building-flashing.rst 给出与本文主题配套的实操步骤。
Simple Boot(单镜像直接启动)
不启用二级引导加载程序时,板卡可加载单个二进制镜像直接运行,这是不带额外配置构建应用的默认选项:
west build -b esp32_devkitc/esp32/procpu samples/hello_world west flash注意:Simple Boot不提供任何安全特性,也不支持 OTA 更新。
使用 MCUboot 引导加载程序(AMP 场景必需)
AMP 需要为两个核分别准备独立分区,因此必须使用 MCUboot 并在板级默认配置中启用:
CONFIG_BOOTLOADER_MCUBOOT=y有两种构建方式:
1. Sysbuild(推荐,自动构建并烧录全部镜像)
west build --sysbuild -b esp32_devkitc/esp32/procpu samples/hello_world默认情况下,sysbuild 会生成 MCUboot 引导加载程序与应用两个镜像,其输出目录按域(domain)组织:
build/ ├── hello_world │ └── zephyr │ ├── zephyr.elf │ └── zephyr.bin ├── mcuboot │ └── zephyr │ ├── zephyr.elf │ └── zephyr.bin └── domains.yaml2. 手动构建(逐个镜像快速迭代)
引导加载程序只需烧录一次,之后可分别构建 PROCPU 与 APPCPU 镜像:
west build -b esp32_devkitc/esp32/procpu samples/hello_world west flash west build -b esp32_devkitc/esp32/appcpu <你的-ipc-应用> west flash加速烧录的实用选项
west flash --esp-skip-flashed:当 flash 中的二进制与待烧录镜像一致时跳过写入(设备端 MD5 校验),加快开发循环;west flash --esp-diff:仅写入与上次烧录镜像存在差异的区域(基于本地缓存对比,若 flash 被其他工具/手动修改过则不要使用);west flash --esp-no-progress:抑制进度输出,适合 CI 场景;west flash --reset-type watchdog-reset:当芯片停留在下载模式无法自动启动新镜像时,用看门狗复位强制重启;west espressif monitor:打开串口监视器,观察 PROCPU 输出。
启动成功后,串口监视器应看到类似输出:
***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** Hello World! <board>参考资料
- 特性文档源文件:boards/espressif/common/soc-esp32-features.rst
- AMP Kconfig:soc/espressif/common/Kconfig.amp
- AMP/SMP 启动实现:soc/espressif/esp32/esp32-mp.c
- 板级双核定义:boards/espressif/esp32_devkitc
- 构建与烧录指南:boards/espressif/common/building-flashing.rst
- ESP32 系列 SoC 支持矩阵:soc/espressif
更详尽的硬件寄存器与电气规格可查阅 ESP32 Datasheet 与 ESP32 Technical Reference Manual(乐鑫官方文档)。若需确认某一外设在 Zephyr 中的驱动支持状态,建议以对应板卡目录下的设备树与supported列表为准。
【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考