组件路径:
C:\project\Common\esp\esp-idf\components\spi_flash
C:\project\Common\esp\esp-idf\components\esp_hal_mspi
我先对照这两个组件的职责、对外 API 和调用关系,再说明该用哪一层。
这两个组件是上下层关系,不是两套平行的 flash 驱动。
esp_hal_mspi管芯片上的 Memory SPI 硬件;spi_flash管 NOR Flash 这颗外设怎么读、写、擦、映射。 应用代码应走spi_flash(或再上层的esp_partition),不要直接调esp_hal_mspi。
一层图
应用 / NVS / SPIFFS / FatFS ↓ esp_partition(分区边界) ↓ spi_flash ← 公共 API:esp_flash_*、spi_flash_mmap ├── 芯片驱动 Winbond / GD / MXIC / ISSI … ├── 主机驱动 memspi_host_driver(封装 HAL) └── OS 适配 关 cache、总线锁、延时、多核 IPC ↓ esp_hal_mspi ← 非公开 HAL/LL:寄存器、时钟、加密、PSRAM ↓ SPI_MEM / SPI1 寄存器(S31 上还有 SPI_MEM_S / SPI_MEM_C)文档也写了:主机驱动依赖esp_hal_mspi/include/hal里的spi_flash_host_driver_t。spi_flash的CMakeLists.txt明确REQUIRES esp_hal_mspi。
esp_hal_mspi:硬件抽象
面向 MSPI 控制器,不关心 Flash 厂家命令集。头文件里写了 不是 public API。
职责大致是:
- 按芯片拆的 LL:
esp32s31/include/hal/mspi_ll.h、spimem_flash_ll.h、gpspi_flash_ll.h、psram_ctrlr_ll.h、spi_flash_encrypted_ll.h、mspi_pms_ll.h - 跨芯片 HAL:
spi_flash_hal.c、加密 HAL、GPSPI HAL - 时钟、dummy、CS hold、QPI/OPI、auto-suspend 的寄存器配置
- Flash + PSRAM 共用 的 MSPI 资源(S31 的
mspi_ll.h注释写得很清楚:影响 Flash 和 PSRAM,但不属于 Flash 芯片驱动)
应用工程几乎不会REQUIRES esp_hal_mspi。bootloader 里大部分 HAL 源文件还不编(NOT BOOTLOADER_BUILD)。
spi_flash:Flash 软件栈
面向 外部 NOR Flash 芯片,提供应用能调用的 API。
职责大致是:
| 能力 | 典型入口 |
|---|---|
读 / 写 / 擦 |
|
内存映射 |
|
接外置 Flash |
|
厂家差异 |
|
关 cache、并发 |
|
高频 / 休眠 | HPM、DPD |
它还要处理 SPI0/1 和指令缓存共用总线:写主 Flash 时必须停 cache、锁总线,否则取指会错。这些是软件/OS 问题,不在 HAL 里。
对照
esp_hal_mspi | spi_flash | |
|---|---|---|
层级 | HAL / LL | 驱动 + OS |
对象 | MSPI 外设(Flash 控制器 + PSRAM) | NOR Flash 芯片 |
对外 | 内部,可能改 |
|
厂家命令 | 无 | ISSI / GD / MXIC / Winbond … |
分区、mmap | 无 | 有 mmap;分区在 |
关 cache / 锁 | 无 | 有 |
谁用 |
| 应用、分区、文件系统 |
改寄存器 | 直接写 | 通过 host driver → HAL |
本工程里该碰哪边
- 读写用户数据、资源分区:用
esp_partition_*,不要直接esp_flash_*。 - 接第二颗 SPI Flash:用
spi_flash的esp_flash_spi_init。 - 自定义不支持的 Flash 型号:改
spi_flash芯片驱动(esp_flash_chips/)。 - 改 dummy、时钟、加密引擎、PSRAM 控制器:才轮到
esp_hal_mspi,而且属于 SoC 移植,不是应用层。
一句话:esp_hal_mspi是 怎么拨 MSPI 寄存器;spi_flash是 怎么安全地操作这颗 Flash。