# SPI flash API

[English]

## 概述

spi_flash 组件提供外部 flash 数据读取、写入、擦除和内存映射相关的 API 函数。

关于更多高层次的用于访问分区（分区表定义于 分区表）的 API 函数，参见 分区 API 。

备注

访问主 flash 芯片时，建议使用上述 `esp_partition_*` API 函数，而非低层级的 `esp_flash_*` API 函数。分区表 API 函数根据存储在分区表中的数据，进行边界检查并计算在 flash 中的正确偏移量。不过，仍支持使用 `esp_flash_*` 函数直接访问外部（额外）的 SPI flash 芯片。

与 ESP-IDF v4.0 之前的 API 不同，这一版 `esp_flash_*` API 功能并不局限于主 SPI flash 芯片（即运行程序的 SPI flash 芯片）。通过使用不同的芯片指针，可以访问连接到 SPI0/1 或 SPI2 总线的外部 flash 芯片。

备注

大多数 `esp_flash_*` API 使用 SPI1，SPI2 等外设而非通过 SPI0 上的 cache。这使得它们不仅能访问主 flash，也能访问外部 flash。

而由于 cache 的限制，所有经过 cache 的操作都只能对主 flash 进行。这些操作的地址同样受到 cache 能力的限制。Cache 无法访问外部 flash 或者高于它能力的地址段。这些 cache 操作包括：mmap、加密读写、执行代码或者访问在 flash 中的变量。

备注

ESP-IDF v4.0 之后的 flash API 不再是 原子 的。因此，如果读操作执行过程中发生写操作，且读操作和写操作的 flash 地址出现重叠，读操作返回的数据可能会包含旧数据和新数据（新数据为写操作更新产生的数据）。

备注

仅有主 flash 芯片支持加密操作，外接（经 SPI1 使用其他不同片选访问，或经其它 SPI 总线访问）的 flash 芯片则不支持加密操作。硬件的限制也决定了仅有主 flash 支持从 cache 当中读取。

## flash 功能支持情况

### 支持的 flash 列表

不同厂家的 flash 特性有不同的操作方式，因此需要特殊的驱动支持。当前驱动支持大多数厂家 flash 24 位地址范围内的快速/慢速读，以及二线模式 (DIO/DOUT)，因为他们不需要任何厂家的自定义命令。

当前驱动支持以下厂家/型号的 flash 的四线模式 (QIO/QOUT)：

1. ISSI

2. GD

3. MXIC

4. FM

5. Winbond

6. XMC

7. BOYA

备注

只有 ESP32-H2 支持上述某个 flash 时，芯片的驱动才默认支持这款 flash。可使用 menuconfig 中的 `Component config` > `SPI flash driver` > `Auto-detect flash chips` 选项来使能/禁用某个 flash。

### flash 可选的功能

有一些功能可能不是所有的 flash 芯片都支持，或不是所有的 ESP 芯片都支持。这些功能包括：

- 32 比特地址的 flash 支持 - 通常意味着拥有大于 16 MB 内存空间的大容量 flash 需要更长的地址去访问。

- flash 的私有 ID (unique ID) - 表示 flash 支持它自己的 64-bit 独有 ID。

- 暂停与恢复 - 表示 flash 可以在读/写的过程中接受暂停/恢复的命令。ESP32-H2 可以在 flash 正在写/擦除的过程中保持 cache 开启，并能随机读取 flash 中的内容。

如果想使用这些功能，则需保证 ESP32-H2 支持这些功能，且产品里所使用的 flash 芯片也要支持这些功能。请参阅 flash 的可选功能，查看更多信息。

也可以自定义 flash 芯片驱动。请参阅 覆盖默认芯片驱动程序，查看详细信息。

## 初始化 flash 设备

在使用 `esp_flash_*` API 之前，需要在 SPI 总线上初始化芯片，步骤如下：

1. 调用 `spi_bus_initialize()` 初始化 SPI 总线。此函数将初始化总线上设备间共享的资源，如 I/O、DMA、中断等。

2. 调用 `spi_bus_add_flash_device()` 将 flash 设备连接到总线上。然后分配内存，填充 `esp_flash_t` 结构体，同时初始化 CS I/O。

3. 调用 `esp_flash_init()` 与芯片进行通信。后续操作会依据芯片类型不同而有差异。

备注

当前，已支持多个 flash 芯片连接到同一总线。

## SPI flash 访问 API

如下所示为处理 flash 中数据的函数集：

- `esp_flash_read()`：将数据从 flash 读取到 RAM；

- `esp_flash_write()`：将数据从 RAM 写入到 flash；

- `esp_flash_erase_region()`：擦除 flash 中指定区域的数据；

- `esp_flash_erase_chip()`：擦除整个 flash；

- `esp_flash_get_chip_size()`：返回 menuconfig 中设置的 flash 芯片容量（以字节为单位）。

一般来说，请尽量避免对主 SPI flash 芯片直接使用原始 SPI flash 函数。如需对主 SPI flash 芯片进行操作，请使用 分区专用函数。

## SPI flash 容量

SPI flash 容量由引导加载程序镜像头部（烧录偏移量为 0x1000）的一个字段进行配置。

默认情况下，引导加载程序被写入 flash 时，`esptool.py` 会自动检测 SPI flash 容量，同时使用正确容量更新引导加载程序的头部。也可以在工程配置中设置 CONFIG_ESPTOOLPY_FLASHSIZE，生成固定的 flash 容量。

如需在运行时覆盖已配置的 flash 容量，请配置 `g_rom_flashchip` 结构中的 `chip_size`。`esp_flash_*` 函数使用此容量（于软件和 ROM 中）进行边界检查。

## SPI1 flash 并发约束

注意

指令/数据 cache（用以执行固件）与 SPI1 外设（由像 SPI flash 驱动一样的驱动程序控制）共享 SPI0/1 总线。因此，在 SPI1 总线上调用 SPI flash API（包括访问主 flash）会对整个系统造成显著的影响。请参阅 SPI1 flash 并发约束，查看详细信息。

## SPI flash 加密

SPI flash 内容支持加密，并在硬件层进行透明解密。

请参阅 flash 加密，查看详细信息。

## 内存映射 API

ESP32-H2 的内存硬件可以将 flash 部分区域映射到指令地址空间和数据地址空间。此映射仅用于读操作，不能通过写入 flash 映射的存储区域来改变 flash 中的内容。

flash 在 64 KB 页进行映射。内存映射硬件既可将 flash 映射到数据地址空间，也能映射到指令地址空间。请查看技术参考手册，了解内存映射硬件的详细信息及有关限制。

请注意，有些页被用于将应用程序映射到内存中，因此实际可用的页会少于硬件提供的总数。

启用 flash 加密 时，使用内存映射区域从 flash 读取数据是解密 flash 的唯一方法，解密需在硬件层进行。

内存映射 API 在 `spi_flash_mmap.h` 和 `esp_partition.h` 中声明：

- `spi_flash_mmap()`：将 flash 物理地址区域映射到 CPU 指令空间或数据空间；

- `spi_flash_munmap()`：取消上述区域的映射；

- `esp_partition_mmap()`：将分区的一部分映射至 CPU 指令空间或数据空间；

`spi_flash_mmap()` 和 `esp_partition_mmap()` 的区别如下：

- `spi_flash_mmap()`：需要给定一个 64 KB 对齐的物理地址；

- `esp_partition_mmap()`：给定分区内任意偏移量即可，此函数根据需要将返回的指针调整至指向映射内存。

内存映射以页为单位，即使传递给 `esp_partition_mmap` 的是一个分区，分区外的数据也是也是可以被读取到的，不会受到分区边界的影响。

备注

由于 mmap 是由 cache 支持的，因此，mmap 也仅能用在主 flash 上。

## SPI flash 实现

`esp_flash_t` 结构体包含芯片数据和该 API 的三个重要部分：

1. 主机驱动，为访问芯片提供硬件支持；

2. 芯片驱动，为不同芯片提供兼容性服务；

3. OS 函数，在不同阶段（一级或二级 Boot 或者应用程序阶段）为部分 OS 函数（如锁、延迟）提供支持。

### 主机驱动

主机驱动依赖 `hal/include/hal` 文件夹下 `spi_flash_types.h` 定义的 `spi_flash_host_driver_t` 接口。该接口提供了一些常用的函数，用于与芯片通信。

在 SPI HAL 文件中，有些函数是基于现有的 ESP32-H2 memory-spi 来实现的。但是，由于 ESP32-H2 的速度限制，HAL 层无法提供某些读命令的高速实现（所以这些命令根本没有在 HAL 的文件中被实现）。`memspi_host_driver.h` 和 `.c` 文件使用 HAL 提供的 `common_command` 函数实现上述读命令的高速版本，并将所有它实现的以及 HAL 函数封装为 `spi_flash_host_driver_t` 供更上层调用。

仅通过 GPIO，也可实现自己的主机驱动。只要实现了 `spi_flash_host_driver_t` 中所有函数，不管底层硬件是什么，esp_flash API 都可以访问 flash。

### 芯片驱动

芯片驱动在 `spi_flash_chip_driver.h` 中进行定义，并将主机驱动提供的基本函数进行封装以供 API 层使用。

有些操作需在执行前先发送命令，或在执行后读取状态，因此有些芯片需要不同的命令或值以及通信方式。

`generic chip` 芯片代表了常见的 flash 芯片，其他芯片驱动可以在这种通用芯片的基础上进行开发。

芯片驱动依赖主机驱动。

### OS 函数

OS 函数层目前支持访问锁和延迟的方法。

锁（见 SPI 总线锁）用于解决同一 SPI 总线上的设备访问和 SPI flash 芯片访问之间的冲突。例如：

1. 经 SPI1 总线访问 flash 芯片时，应当禁用 cache（平时用于获取代码和 PSRAM 数据）。

2. 经其他总线访问 flash 芯片时，应当禁用 flash 上 SPI 主驱动器注册的 ISR 以避免冲突。

3. SPI 主驱动器上某些没有 CS 线或者 CS 线受软件（如 SDSPI）控制的设备需要在一段时间内独占总线。

延时则用于某些长时操作，需要主机处于等待状态或执行轮询。

顶层 API 将芯片驱动和 OS 函数封装成一个完整的组件，并提供参数检查。

使用 OS 函数还可以在一定程度上避免在擦除大块 flash 区域时出现看门狗超时的情况。在这段时间内，CPU 将被 flash 擦除任务占用，从而阻止其他任务的执行，包括为看门狗定时器 (WDT) 供电的空闲任务。若已选中配置选项 CONFIG_ESP_TASK_WDT_PANIC，并且 flash 操作时间长于看门狗的超时时间，系统将重新启动。

不过，由于不同的 flash 芯片擦除时间不同，flash 驱动几乎无法兼容，很难完全规避超时的风险，这一点需要格外注意。请遵照以下指南：

1. 建议启用 CONFIG_SPI_FLASH_YIELD_DURING_ERASE 选项，允许调度器在擦除 flash 时进行重新调度。此外，还可以使用下列参数。

- 在 menuconfig 中增加 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS 或减少 CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS 的时间。

- 在 menuconfig 中增加 CONFIG_ESP_TASK_WDT_TIMEOUT_S 的时间，以设置更长的看门狗超时周期。然而，看门狗超时周期拉长后，可能无法再检测到以前可检测到的超时。

1. 请注意，在进行长时间的 SPI flash 操作时，启用 CONFIG_ESP_TASK_WDT_PANIC 选项将会在超时时触发紧急处理程序。不过，启用该选项也可以帮助处理应用程序中的意外异常，请根据实际情况决定是否需要启用这个选项。

2. 在开发过程中，请根据项目对擦除 flash 的具体要求和时间限制，谨慎进行 flash 操作。在配置 flash 擦除超时周期时，请在实际产品要求的基础上留出合理的冗余时间，从而提高产品的可靠性。

## 实现细节

必须确保操作期间，两个 CPU 均未从 flash 运行代码，实现细节如下：

- 单核模式下，SDK 在执行 flash 操作前将禁用中断或调度算法。

- 双核模式下，SDK 需确保两个 CPU 均未运行 flash 代码。

如果有 SPI flash API 在 CPU A（PRO 或 APP）上调用，它使用 `esp_ipc_call` API 在 CPU B 上运行 `spi_flash_op_block_func` 函数。`esp_ipc_call` API 会在 CPU B 上唤醒一个高优先级任务，即运行 `spi_flash_op_block_func` 函数。运行该函数将禁用 CPU B 上的 cache，并使用 `s_flash_op_can_start` 旗帜来标志 cache 已禁用。然后，CPU A 上的任务也会禁用 cache 并继续执行 flash 操作。

执行 flash 操作时，CPU A 和 CPU B 仍然可以执行中断操作。默认中断代码均存储于 RAM 中，如果新添加了中断分配 API，则应添加一个标志位以请求在 flash 操作期间禁用该新分配的中断。

flash 操作完成后，CPU A 上的函数将设置另一标志位，即 `s_flash_op_complete`，用以通知 CPU B 上的任务可以重新启用 cache 并释放 CPU。接着，CPU A 上的函数也重新启用 cache，并将控制权返还给调用者。

另外，所有 API 函数均受互斥量 `s_flash_op_mutex` 保护。

在单核环境中（启用 CONFIG_FREERTOS_UNICORE），需要禁用上述两个 cache，以防发生 CPU 间通信。

## flash 驱动的内部存储优化

ESP-IDF 提供了优化 IRAM 使用的选项。通过禁用 CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM 选项，可以选择性地将某些函数地放入 flash，使 SPI flash 操作函数在 flash 中执行，而不是从 IRAM 中执行。这种方式能够节省 IRAM 内存，用于其他对时间敏感的函数或任务。

然而，这种方式对 flash 性能具有一定的影响。与 IRAM 中的函数相比，放在 flash 中的函数执行时间可能略有增加。因此对于具有严格时序要求或严重依赖 SPI flash 操作的应用程序，采取此方式前需进行权衡。

备注

未启用 CONFIG_SPI_FLASH_AUTO_SUSPEND 时，不应禁用 CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM，否则会导致严重崩溃。关于 flash 挂起功能，请参阅 flash 自动暂停功能。

### 资源消耗

使用 IDF Size 工具来检查 SPI flash 驱动的代码和数据消耗。以下是测试条件（以 ESP32-C2 为例）：

请注意，以下数据并非精确值，仅供参考；不同芯片型号可能会有所差异。

启用 CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM 时的资源消耗如下表所示：

选项启用时的资源消耗
组件层 | 总大小 | DIRAM | .bss | .data | .text | flash 代码 | .text | flash 数据 | .rodata
--- | --- | --- | --- | --- | --- | --- | --- | --- | ---
hal | 4624 | 4038 | 0 | 0 | 4038 | 586 | 586 | 0 | 0
spi_flash | 14074 | 11597 | 82 | 1589 | 9926 | 2230 | 2230 | 247 | 247

禁用 CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM 时的资源消耗如下表所示：

选项禁用时的资源消耗
组件层 | 总大小 | DIRAM | .bss | .data | .text | flash 代码 | .text | flash 数据 | .rodata
--- | --- | --- | --- | --- | --- | --- | --- | --- | ---
hal | 4632 | 0 | 0 | 0 | 0 | 4632 | 4632 | 0 | 0
spi_flash | 14569 | 1399 | 22 | 429 | 948 | 11648 | 11648 | 1522 | 1522

## 相关文档

- flash 的可选功能

- SPI1 flash 并发约束

- SPI Flash API ESP-IDF 版本与芯片 ROM 版本的对比

## SPI flash API 参考

### Header File

- components/spi_flash/include/esp_flash_spi_init.h

- This header file can be included with:

  >     #include "esp_flash_spi_init.h"

- This header file is a part of the API provided by the `spi_flash` component. To declare that your component depends on `spi_flash`, add the following to your CMakeLists.txt:

  >     REQUIRES spi_flash

  > or

  >     PRIV_REQUIRES spi_flash

### Functions

esp_err_t spi_bus_add_flash_device(esp_flash_t **out_chip, const esp_flash_spi_device_config_t *config)

  Add a SPI Flash device onto the SPI bus.

  The bus should be already initialized by `spi_bus_initialization`.

  参数:

    - out_chip -- Pointer to hold the initialized chip.

    - config -- Configuration of the chips to initialize.

  返回:

    - ESP_ERR_INVALID_ARG: out_chip is NULL, or some field in the config is invalid.

    - ESP_ERR_NO_MEM: failed to allocate memory for the chip structures.

    - ESP_OK: success.

esp_err_t spi_bus_remove_flash_device(esp_flash_t *chip)

  Remove a SPI Flash device from the SPI bus.

  参数:

    chip -- The flash device to remove.

  返回:

    - ESP_ERR_INVALID_ARG: The chip is invalid.

    - ESP_OK: success.

### Structures

struct esp_flash_spi_device_config_t

  Configurations for the SPI Flash to init.

  Public Members

  spi_host_device_t host_id

    Bus to use.

  int cs_io_num

    GPIO pin to output the CS signal.

  esp_flash_io_mode_t io_mode

    IO mode to read from the Flash.

  enum esp_flash_speed_s speed

    Speed of the Flash clock. Replaced by freq_mhz.

  int input_delay_ns

    Input delay of the data pins, in ns. Set to 0 if unknown.

  int cs_id

    CS line ID, ignored when not `host_id` is not SPI1_HOST, or `CONFIG_SPI_FLASH_SHARE_SPI1_BUS` is enabled. In this case, the CS line used is automatically assigned by the SPI bus lock.

  int freq_mhz

    The frequency of flash chip(MHZ)

  spi_clock_source_t clock_source

    Select SPI clock source, `SPI_CLK_SRC_DEFAULT` by default.

### Header File

- components/spi_flash/include/esp_flash.h

- This header file can be included with:

  >     #include "esp_flash.h"

- This header file is a part of the API provided by the `spi_flash` component. To declare that your component depends on `spi_flash`, add the following to your CMakeLists.txt:

  >     REQUIRES spi_flash

  > or

  >     PRIV_REQUIRES spi_flash

### Functions

esp_err_t esp_flash_init(esp_flash_t *chip)

  Initialise SPI flash chip interface.

  This function must be called before any other API functions are called for this chip.

  备注

  Only the `host` and `read_mode` fields of the chip structure must be initialised before this function is called. Other fields may be auto-detected if left set to zero or NULL.

  备注

  If the chip->drv pointer is NULL, chip chip_drv will be auto-detected based on its manufacturer & product IDs. See `esp_flash_registered_flash_drivers` pointer for details of this process.

  参数:

    chip -- Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted.

  返回:

    ESP_OK on success, or a flash error code if initialisation fails.

bool esp_flash_chip_driver_initialized(const esp_flash_t *chip)

  Check if appropriate chip driver is set.

  参数:

    chip -- Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted.

  返回:

    true if set, otherwise false.

esp_err_t esp_flash_read_id(esp_flash_t *chip, uint32_t *out_id)

  Read flash ID via the common "RDID" SPI flash command.

  ID is a 24-bit value. Lower 16 bits of 'id' are the chip ID, upper 8 bits are the manufacturer ID.

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

    - out_id -- [out] Pointer to receive ID value.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size)

  Detect flash size based on flash ID.

  备注

  1. Most flash chips use a common format for flash ID, where the lower 4 bits specify the size as a power of 2. If the manufacturer doesn't follow this convention, the size may be incorrectly detected.

  1. The out_size returned only stands for The out_size stands for the size in the binary image header. If you want to get the real size of the chip, please call `esp_flash_get_physical_size` instead.

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

    - out_size -- [out] Detected size in bytes, standing for the size in the binary image header.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size)

  Detect flash size based on flash ID.

  备注

  Most flash chips use a common format for flash ID, where the lower 4 bits specify the size as a power of 2. If the manufacturer doesn't follow this convention, the size may be incorrectly detected.

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

    - flash_size -- [out] Detected size in bytes.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_read_unique_chip_id(esp_flash_t *chip, uint64_t *out_id)

  Read flash unique ID via the common "RDUID" SPI flash command.

  ID is a 64-bit value.

  备注

  This is an optional feature, which is not supported on all flash chips. READ PROGRAMMING GUIDE FIRST!

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init().

    - out_id -- [out] Pointer to receive unique ID value.

  返回:

    - ESP_OK on success, or a flash error code if operation failed.

    - ESP_ERR_NOT_SUPPORTED if the chip doesn't support read id.

esp_err_t esp_flash_erase_chip(esp_flash_t *chip)

  Erase flash chip contents.

  参数:

    chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

  返回:

    - ESP_OK on success,

    - ESP_ERR_NOT_SUPPORTED if the chip is not able to perform the operation. This is indicated by WREN = 1 after the command is sent.

    - ESP_ERR_NOT_ALLOWED if a read-only partition is present.

    - Other flash error code if operation failed.

esp_err_t esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len)

  Erase a region of the flash chip.

  Sector size is specified in chip->drv->sector_size field (typically 4096 bytes.) ESP_ERR_INVALID_ARG will be returned if the start & length are not a multiple of this size.

  Erase is performed using block (multi-sector) erases where possible (block size is specified in chip->drv->block_erase_size field, typically 65536 bytes). Remaining sectors are erased using individual sector erase commands.

  参数:

    - chip -- Pointer to identify flash chip. If NULL, esp_flash_default_chip is substituted. Must have been successfully initialised via esp_flash_init()

    - start -- Address to start erasing flash. Must be sector aligned.

    - len -- Length of region to erase. Must also be sector aligned.

  返回:

    - ESP_OK on success,

    - ESP_ERR_NOT_SUPPORTED if the chip is not able to perform the operation. This is indicated by WREN = 1 after the command is sent.

    - ESP_ERR_NOT_ALLOWED if the address range (start – start + len) overlaps with a read-only partition address space

    - Other flash error code if operation failed.

esp_err_t esp_flash_get_chip_write_protect(esp_flash_t *chip, bool *write_protected)

  Read if the entire chip is write protected.

  备注

  A correct result for this flag depends on the SPI flash chip model and chip_drv in use (via the 'chip->drv' field).

  参数:

    - chip -- Pointer to identify flash chip. If NULL, esp_flash_default_chip is substituted. Must have been successfully initialised via esp_flash_init()

    - write_protected -- [out] Pointer to boolean, set to the value of the write protect flag.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_set_chip_write_protect(esp_flash_t *chip, bool write_protect)

  Set write protection for the SPI flash chip.

  Some SPI flash chips may require a power cycle before write protect status can be cleared. Otherwise, write protection can be removed via a follow-up call to this function.

  备注

  Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use (via the 'chip->drv' field).

  参数:

    - chip -- Pointer to identify flash chip. If NULL, esp_flash_default_chip is substituted. Must have been successfully initialised via esp_flash_init()

    - write_protect -- Boolean value for the write protect flag

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_get_protectable_regions(const esp_flash_t *chip, const esp_flash_region_t **out_regions, uint32_t *out_num_regions)

  Read the list of individually protectable regions of this SPI flash chip.

  备注

  Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use (via the 'chip->drv' field).

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

    - out_regions -- [out] Pointer to receive a pointer to the array of protectable regions of the chip.

    - out_num_regions -- [out] Pointer to an integer receiving the count of protectable regions in the array returned in 'regions'.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_get_protected_region(esp_flash_t *chip, const esp_flash_region_t *region, bool *out_protected)

  Detect if a region of the SPI flash chip is protected.

  备注

  It is possible for this result to be false and write operations to still fail, if protection is enabled for the entire chip.

  备注

  Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use (via the 'chip->drv' field).

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

    - region -- Pointer to a struct describing a protected region. This must match one of the regions returned from esp_flash_get_protectable_regions(...).

    - out_protected -- [out] Pointer to a flag which is set based on the protected status for this region.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_set_protected_region(esp_flash_t *chip, const esp_flash_region_t *region, bool protect)

  Update the protected status for a region of the SPI flash chip.

  备注

  It is possible for the region protection flag to be cleared and write operations to still fail, if protection is enabled for the entire chip.

  备注

  Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use (via the 'chip->drv' field).

  参数:

    - chip -- Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init()

    - region -- Pointer to a struct describing a protected region. This must match one of the regions returned from esp_flash_get_protectable_regions(...).

    - protect -- Write protection flag to set.

  返回:

    ESP_OK on success, or a flash error code if operation failed.

esp_err_t esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length)

  Read data from the SPI flash chip.

  There are no alignment constraints on buffer, address or length.

  备注

  If on-chip flash encryption is used, this function returns raw (ie encrypted) data. Use the flash cache to transparently decrypt data.

  参数:

    - chip -- Pointer to identify flash chip. If NULL, esp_flash_default_chip is substituted. Must have been successfully initialised via esp_flash_init()

    - buffer -- Pointer to a buffer where the data will be read. To get better performance, this should be in the DRAM and word aligned.

    - address -- Address on flash to read from. Must be less than chip->size field.

    - length -- Length (in bytes) of data to read.

  返回:

    - ESP_OK: success

    - ESP_ERR_NO_MEM: Buffer is in external PSRAM which cannot be concurrently accessed, and a temporary internal buffer could not be allocated.

    - or a flash error code if operation failed.

esp_err_t esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length)

  Write data to the SPI flash chip.

  There are no alignment constraints on buffer, address or length.

  参数:

    - chip -- Pointer to identify flash chip. If NULL, esp_flash_default_chip is substituted. Must have been successfully initialised via esp_flash_init()

    - address -- Address on flash to write to. Must be previously erased (SPI NOR flash can only write bits 1->0).

    - buffer -- Pointer to a buffer with the data to write. To get better performance, this should be in the DRAM and word aligned.

    - length -- Length (in bytes) of data to write.

  返回:

    - ESP_OK on success

    - ESP_FAIL, bad write, this will be detected only when CONFIG_SPI_FLASH_VERIFY_WRITE is enabled

    - ESP_ERR_NOT_SUPPORTED if the chip is not able to perform the operation. This is indicated by WREN = 1 after the command is sent.

    - ESP_ERR_NOT_ALLOWED if the address range (address – address + length) overlaps with a read-only partition address space

    - Other flash error code if operation failed.

esp_err_t esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length)

  Encrypted and write data to the SPI flash chip using on-chip hardware flash encryption.

  备注

  Both address & length must be 16 byte aligned, as this is the encryption block size

  参数:

    - chip -- Pointer to identify flash chip. Must be NULL (the main flash chip). For other chips, encrypted write is not supported.

    - address -- Address on flash to write to. 16 byte aligned. Must be previously erased (SPI NOR flash can only write bits 1->0).

    - buffer -- Pointer to a buffer with the data to write.

    - length -- Length (in bytes) of data to write. 16 byte aligned.

  返回:

    - ESP_OK: on success

    - ESP_FAIL: bad write, this will be detected only when CONFIG_SPI_FLASH_VERIFY_WRITE is enabled

    - ESP_ERR_NOT_SUPPORTED: encrypted write not supported for this chip.

    - ESP_ERR_INVALID_ARG: Either the address, buffer or length is invalid.

    - ESP_ERR_NOT_ALLOWED if the address range (address – address + length) overlaps with a read-only partition address space

esp_err_t esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length)

  Read and decrypt data from the SPI flash chip using on-chip hardware flash encryption.

  参数:

    - chip -- Pointer to identify flash chip. Must be NULL (the main flash chip). For other chips, encrypted read is not supported.

    - address -- Address on flash to read from.

    - out_buffer -- Pointer to a buffer for the data to read to.

    - length -- Length (in bytes) of data to read.

  返回:

    - ESP_OK: on success

    - ESP_ERR_NOT_SUPPORTED: encrypted read not supported for this chip.

static inline bool esp_flash_is_quad_mode(const esp_flash_t *chip)

  Returns true if chip is configured for Quad I/O or Quad Fast Read.

  参数:

    chip -- Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted.

  返回:

    true if flash works in quad mode, otherwise false

### Structures

struct esp_flash_region_t

  Structure for describing a region of flash.

  Public Members

  uint32_t offset

    Start address of this region.

  uint32_t size

    Size of the region.

struct esp_flash_os_functions_t

  OS-level integration hooks for accessing flash chips inside a running OS.

  It's in the public header because some instances should be allocated statically in the startup code. May be updated according to hardware version and new flash chip feature requirements, shouldn't be treated as public API.

  For advanced developers, you may replace some of them with your implementations at your own risk.

  Public Members

  esp_err_t (*start)(void *arg, uint32_t flags)

    Called before commencing any flash operation. Does not need to be recursive (ie is called at most once for each call to 'end').

  esp_err_t (*end)(void *arg)

    Called after completing any flash operation.

  esp_err_t (*region_protected)(void *arg, size_t start_addr, size_t size)

    Called before any erase/write operations to check whether the region is limited by the OS

  esp_err_t (*delay_us)(void *arg, uint32_t us)

    Delay for at least 'us' microseconds. Called in between 'start' and 'end'.

  void *(*get_temp_buffer)(void *arg, size_t reqest_size, size_t *out_size)

    Called for get temp buffer when buffer from application cannot be directly read into/write from.

  void (*release_temp_buffer)(void *arg, void *temp_buf)

    Called for release temp buffer.

  esp_err_t (*check_yield)(void *arg, uint32_t chip_status, uint32_t *out_request)

    Yield to other tasks. Called during erase operations.

    Return:

      ESP_OK means yield needs to be called (got an event to handle), while ESP_ERR_TIMEOUT means skip yield.

  esp_err_t (*yield)(void *arg, uint32_t *out_status)

    Yield to other tasks. Called during erase operations.

  int64_t (*get_system_time)(void *arg)

    Called for get system time.

  void (*set_flash_op_status)(uint32_t op_status)

    Call to set flash operation status

struct esp_flash_t

  Structure to describe a SPI flash chip connected to the system.

  Structure must be initialized before use (passed to esp_flash_init()). It's in the public header because some instances should be allocated statically in the startup code. May be updated according to hardware version and new flash chip feature requirements, shouldn't be treated as public API.

  For advanced developers, you may replace some of them with your implementations at your own risk.

  Public Members

  spi_flash_host_inst_t *host

    Pointer to hardware-specific "host_driver" structure. Must be initialized before used.

  const spi_flash_chip_t *chip_drv

    Pointer to chip-model-specific "adapter" structure. If NULL, will be detected during initialisation.

  const esp_flash_os_functions_t *os_func

    Pointer to os-specific hook structure. Call `esp_flash_init_os_functions()` to setup this field, after the host is properly initialized.

  void *os_func_data

    Pointer to argument for os-specific hooks. Left NULL and will be initialized with `os_func`.

  esp_flash_io_mode_t read_mode

    Configured SPI flash read mode. Set before `esp_flash_init` is called.

  uint32_t size

    Size of SPI flash in bytes. If 0, size will be detected during initialisation. Note: this stands for the size in the binary image header. If you want to get the flash physical size, please call `esp_flash_get_physical_size`.

  uint32_t chip_id

    Detected chip id.

  uint32_t busy

    This flag is used to verify chip's status.

  uint32_t hpm_dummy_ena

    This flag is used to verify whether flash works under HPM status.

  uint32_t reserved_flags

    reserved.

  int clock_source

    Clock source for GPSPI.

### Macros

ESP_FLASH_START_FLAG_LIMIT_CPU_FREQ

  Flags for start function Limit CPU frequency during flash operations (ESP32-C5 only, 240MHz).

SPI_FLASH_YIELD_REQ_YIELD

SPI_FLASH_YIELD_REQ_SUSPEND

SPI_FLASH_YIELD_STA_RESUME

SPI_FLASH_OS_IS_ERASING_STATUS_FLAG

### Type Definitions

typedef struct spi_flash_chip_t spi_flash_chip_t

### Header File

- components/spi_flash/include/spi_flash_mmap.h

- This header file can be included with:

  >     #include "spi_flash_mmap.h"

- This header file is a part of the API provided by the `spi_flash` component. To declare that your component depends on `spi_flash`, add the following to your CMakeLists.txt:

  >     REQUIRES spi_flash

  > or

  >     PRIV_REQUIRES spi_flash

### Functions

esp_err_t spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_memory_t memory, const void **out_ptr, spi_flash_mmap_handle_t *out_handle)

  Map region of flash memory into data or instruction address space.

  This function allocates sufficient number of 64kB MMU pages and configures them to map the requested region of flash memory into the address space. It may reuse MMU pages which already provide the required mapping.

  As with any allocator, if mmap/munmap are heavily used then the address space may become fragmented. To troubleshoot issues with page allocation, use spi_flash_mmap_dump() function.

  参数:

    - src_addr -- Physical address in flash where requested region starts. This address must be aligned to 64kB boundary (SPI_FLASH_MMU_PAGE_SIZE)

    - size -- Size of region to be mapped. This size will be rounded up to a 64kB boundary

    - memory -- Address space where the region should be mapped (data or instruction)

    - out_ptr -- [out] Output, pointer to the mapped memory region

    - out_handle -- [out] Output, handle which should be used for spi_flash_munmap call

  返回:

    ESP_OK on success, ESP_ERR_NO_MEM if pages can not be allocated

esp_err_t spi_flash_mmap_pages(const int *pages, size_t page_count, spi_flash_mmap_memory_t memory, const void **out_ptr, spi_flash_mmap_handle_t *out_handle)

  Map sequences of pages of flash memory into data or instruction address space.

  This function allocates sufficient number of 64kB MMU pages and configures them to map the indicated pages of flash memory contiguously into address space. In this respect, it works in a similar way as spi_flash_mmap() but it allows mapping a (maybe non-contiguous) set of pages into a contiguous region of memory.

  参数:

    - pages -- An array of numbers indicating the 64kB pages in flash to be mapped contiguously into memory. These indicate the indexes of the 64kB pages, not the byte-size addresses as used in other functions. Array must be located in internal memory.

    - page_count -- Number of entries in the pages array

    - memory -- Address space where the region should be mapped (instruction or data)

    - out_ptr -- [out] Output, pointer to the mapped memory region

    - out_handle -- [out] Output, handle which should be used for spi_flash_munmap call

  返回:

    - ESP_OK on success

    - ESP_ERR_NO_MEM if pages can not be allocated

    - ESP_ERR_INVALID_ARG if pagecount is zero or pages array is not in internal memory

void spi_flash_munmap(spi_flash_mmap_handle_t handle)

  Release region previously obtained using spi_flash_mmap.

  备注

  Calling this function will not necessarily unmap memory region. Region will only be unmapped when there are no other handles which reference this region. In case of partially overlapping regions it is possible that memory will be unmapped partially.

  参数:

    handle -- Handle obtained from spi_flash_mmap

void spi_flash_mmap_dump(void)

  Display information about mapped regions.

  This function lists handles obtained using spi_flash_mmap, along with range of pages allocated to each handle. It also lists all non-zero entries of MMU table and corresponding reference counts.

uint32_t spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory)

  get free pages number which can be mmap

  This function will return number of free pages available in mmu table. This could be useful before calling actual spi_flash_mmap (maps flash range to DCache or ICache memory) to check if there is sufficient space available for mapping.

  参数:

    memory -- memory type of MMU table free page

  返回:

    number of free pages which can be mmaped

size_t spi_flash_cache2phys(const void *cached)

  Given a memory address where flash is mapped, return the corresponding physical flash offset.

  Cache address does not have have been assigned via spi_flash_mmap(), any address in memory mapped flash space can be looked up.

  参数:

    cached -- Pointer to flashed cached memory.

  返回:

    - SPI_FLASH_CACHE2PHYS_FAIL If cache address is outside flash cache region, or the address is not mapped.

    - Otherwise, returns physical offset in flash

const void *spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memory)

  Given a physical offset in flash, return the address where it is mapped in the memory space.

  Physical address does not have to have been assigned via spi_flash_mmap(), any address in flash can be looked up.

  备注

  Only the first matching cache address is returned. If MMU flash cache table is configured so multiple entries point to the same physical address, there may be more than one cache address corresponding to that physical address. It is also possible for a single physical address to be mapped to both the IROM and DROM regions.

  备注

  This function doesn't impose any alignment constraints, but if memory argument is SPI_FLASH_MMAP_INST and phys_offs is not 4-byte aligned, then reading from the returned pointer will result in a crash.

  参数:

    - phys_offs -- Physical offset in flash memory to look up.

    - memory -- Address space type to look up a flash cache address mapping for (instruction or data)

  返回:

    - NULL if the physical address is invalid or not mapped to flash cache of the specified memory type.

    - Cached memory address (in IROM or DROM space) corresponding to phys_offs.

### Macros

ESP_ERR_FLASH_OP_FAIL

  This file contains `spi_flash_mmap_xx` APIs, mainly for doing memory mapping to an SPI0-connected external Flash, as well as some helper functions to convert between virtual and physical address

ESP_ERR_FLASH_OP_TIMEOUT

SPI_FLASH_SEC_SIZE

  SPI Flash sector size

SPI_FLASH_MMU_PAGE_SIZE

  Flash cache MMU mapping page size

SPI_FLASH_CACHE2PHYS_FAIL

### Type Definitions

typedef uint32_t spi_flash_mmap_handle_t

  Opaque handle for memory region obtained from spi_flash_mmap.

### Enumerations

enum spi_flash_mmap_memory_t

  Enumeration which specifies memory space requested in an mmap call.

  Values:

  enumerator SPI_FLASH_MMAP_DATA

    map to data memory, allows byte-aligned access

  enumerator SPI_FLASH_MMAP_INST

    map to instruction memory, allows only 4-byte-aligned access

### Header File

- components/hal/include/hal/spi_flash_types.h

- This header file can be included with:

  >     #include "hal/spi_flash_types.h"

### Structures

struct spi_flash_trans_t

  Definition of a common transaction. Also holds the return value.

  Public Members

  uint8_t reserved

    Reserved, must be 0.

  uint8_t mosi_len

    Output data length, in bytes.

  uint8_t miso_len

    Input data length, in bytes.

  uint8_t address_bitlen

    Length of address in bits, set to 0 if command does not need an address.

  uint32_t address

    Address to perform operation on.

  const uint8_t *mosi_data

    Output data to salve.

  uint8_t *miso_data

    [out] Input data from slave, little endian

  uint32_t flags

    Flags for this transaction. Set to 0 for now.

  uint16_t command

    Command to send.

  uint8_t dummy_bitlen

    Basic dummy bits to use.

  uint32_t io_mode

    Flash working mode when `SPI_FLASH_IGNORE_BASEIO` is specified.

struct spi_flash_sus_cmd_conf

  Configuration structure for the flash chip suspend feature.

  Public Members

  uint32_t sus_mask

    SUS/SUS1/SUS2 bit in flash register.

  uint32_t cmd_rdsr

    Read flash status register(2) command.

  uint32_t sus_cmd

    Flash suspend command.

  uint32_t res_cmd

    Flash resume command.

  uint32_t reserved

    Reserved, set to 0.

struct spi_flash_encryption_t

  Structure for flash encryption operations.

  Public Members

  void (*flash_encryption_enable)(void)

    Enable the flash encryption.

  void (*flash_encryption_disable)(void)

    Disable the flash encryption.

  void (*flash_encryption_data_prepare)(uint32_t address, const uint32_t *buffer, uint32_t size)

    Prepare flash encryption before operation.

    备注

    address and buffer must be 8-word aligned.

    Param address:

      The destination address in flash for the write operation.

    Param buffer:

      Data for programming

    Param size:

      Size to program.

  void (*flash_encryption_done)(void)

    flash data encryption operation is done.

  void (*flash_encryption_destroy)(void)

    Destroy encrypted result

  bool (*flash_encryption_check)(uint32_t address, uint32_t length)

    Check if is qualified to encrypt the buffer

    Param address:

      the address of written flash partition.

    Param length:

      Buffer size.

struct spi_flash_host_inst_t

  SPI Flash Host driver instance

  Public Members

  const struct spi_flash_host_driver_s *driver

    Pointer to the implementation function table.

struct spi_flash_host_driver_s

  Host driver configuration and context structure.

  Public Members

  esp_err_t (*dev_config)(spi_flash_host_inst_t *host)

    Configure the device-related register before transactions. This saves some time to re-configure those registers when we send continuously

  esp_err_t (*common_command)(spi_flash_host_inst_t *host, spi_flash_trans_t *t)

    Send an user-defined spi transaction to the device.

  esp_err_t (*read_id)(spi_flash_host_inst_t *host, uint32_t *id)

    Read flash ID.

  void (*erase_chip)(spi_flash_host_inst_t *host)

    Erase whole flash chip.

  void (*erase_sector)(spi_flash_host_inst_t *host, uint32_t start_address)

    Erase a specific sector by its start address.

  void (*erase_block)(spi_flash_host_inst_t *host, uint32_t start_address)

    Erase a specific block by its start address.

  esp_err_t (*read_status)(spi_flash_host_inst_t *host, uint8_t *out_sr)

    Read the status of the flash chip.

  esp_err_t (*set_write_protect)(spi_flash_host_inst_t *host, bool wp)

    Disable write protection.

  void (*program_page)(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)

    Program a page of the flash. Check `max_write_bytes` for the maximum allowed writing length.

  bool (*supports_direct_write)(spi_flash_host_inst_t *host, const void *p)

    Check whether the SPI host supports direct write.

    When cache is disabled, SPI1 doesn't support directly write when buffer isn't internal.

  int (*write_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size)

    Slicer for write data. The `program_page` should be called iteratively with the return value of this function.

    Param address:

      Beginning flash address to write

    Param len:

      Length request to write

    Param align_addr:

      Output of the aligned address to write to

    Param page_size:

      Physical page size of the flash chip

    Return:

      Length that can be actually written in one `program_page` call

  esp_err_t (*read)(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)

    Read data from the flash. Check `max_read_bytes` for the maximum allowed reading length.

  bool (*supports_direct_read)(spi_flash_host_inst_t *host, const void *p)

    Check whether the SPI host supports direct read.

    When cache is disabled, SPI1 doesn't support directly read when the given buffer isn't internal.

  int (*read_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size)

    Slicer for read data. The `read` should be called iteratively with the return value of this function.

    Param address:

      Beginning flash address to read

    Param len:

      Length request to read

    Param align_addr:

      Output of the aligned address to read

    Param page_size:

      Physical page size of the flash chip

    Return:

      Length that can be actually read in one `read` call

  uint32_t (*host_status)(spi_flash_host_inst_t *host)

    Check the host status, 0:busy, 1:idle, 2:suspended.

  esp_err_t (*configure_host_io_mode)(spi_flash_host_inst_t *host, uint32_t command, uint32_t addr_bitlen, int dummy_bitlen_base, esp_flash_io_mode_t io_mode)

    Configure the host to work at different read mode. Responsible to compensate the timing and set IO mode.

  void (*poll_cmd_done)(spi_flash_host_inst_t *host)

    Internal use, poll the HW until the last operation is done.

  esp_err_t (*flush_cache)(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)

    For some host (SPI1), they are shared with a cache. When the data is modified, the cache needs to be flushed. Left NULL if not supported.

  void (*check_suspend)(spi_flash_host_inst_t *host)

    Suspend check erase/program operation, reserved for ESP32-C3 and ESP32-S3 spi flash ROM IMPL.

  void (*resume)(spi_flash_host_inst_t *host)

    Resume flash from suspend manually

  void (*suspend)(spi_flash_host_inst_t *host)

    Set flash in suspend status manually

  esp_err_t (*sus_setup)(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)

    Suspend feature setup for setting cmd and status register mask.

### Macros

SPI_FLASH_TRANS_FLAG_CMD16

  Send command of 16 bits.

SPI_FLASH_TRANS_FLAG_IGNORE_BASEIO

  Not applying the basic io mode configuration for this transaction.

SPI_FLASH_TRANS_FLAG_BYTE_SWAP

  Used for DTR mode, to swap the bytes of a pair of rising/falling edge.

SPI_FLASH_TRANS_FLAG_PE_CMD

  Indicates that this transaction is to erase/program flash chip.

SPI_FLASH_CONFIG_CONF_BITS

  OR the io_mode with this mask, to enable the dummy output feature or replace the first several dummy bits into address to meet the requirements of conf bits. (Used in DIO/QIO/OIO mode)

SPI_FLASH_OPI_FLAG

  A flag for flash work in opi mode, the io mode below are opi, above are SPI/QSPI mode. DO NOT use this value in any API.

SPI_FLASH_READ_MODE_MIN

  Slowest io mode supported by ESP32, currently SlowRd.

### Type Definitions

typedef enum esp_flash_speed_s esp_flash_speed_t

  SPI flash clock speed values, always refer to them by the enum rather than the actual value (more speed may be appended into the list).

  A strategy to select the maximum allowed speed is to enumerate from the `ESP_FLSH_SPEED_MAX-1` or highest frequency supported by your flash, and decrease the speed until the probing success.

typedef struct spi_flash_host_driver_s spi_flash_host_driver_t

### Enumerations

enum esp_flash_speed_s

  SPI flash clock speed values, always refer to them by the enum rather than the actual value (more speed may be appended into the list).

  A strategy to select the maximum allowed speed is to enumerate from the `ESP_FLSH_SPEED_MAX-1` or highest frequency supported by your flash, and decrease the speed until the probing success.

  Values:

  enumerator ESP_FLASH_5MHZ

    The flash runs under 5MHz.

  enumerator ESP_FLASH_10MHZ

    The flash runs under 10MHz.

  enumerator ESP_FLASH_20MHZ

    The flash runs under 20MHz.

  enumerator ESP_FLASH_26MHZ

    The flash runs under 26MHz.

  enumerator ESP_FLASH_40MHZ

    The flash runs under 40MHz.

  enumerator ESP_FLASH_80MHZ

    The flash runs under 80MHz.

  enumerator ESP_FLASH_120MHZ

    The flash runs under 120MHz, 120MHZ can only be used by main flash after timing tuning in system. Do not use this directly in any API.

  enumerator ESP_FLASH_SPEED_MAX

    The maximum frequency supported by the host is `ESP_FLASH_SPEED_MAX-1`.

enum esp_flash_io_mode_t

  Mode used for reading from SPI flash.

  Values:

  enumerator SPI_FLASH_SLOWRD

    Data read using single I/O, some limits on speed.

  enumerator SPI_FLASH_FASTRD

    Data read using single I/O, no limit on speed.

  enumerator SPI_FLASH_DOUT

    Data read using dual I/O.

  enumerator SPI_FLASH_DIO

    Both address & data transferred using dual I/O.

  enumerator SPI_FLASH_QOUT

    Data read using quad I/O.

  enumerator SPI_FLASH_QIO

    Both address & data transferred using quad I/O.

  enumerator SPI_FLASH_OPI_STR

    Only support on OPI flash, flash read and write under STR mode.

  enumerator SPI_FLASH_OPI_DTR

    Only support on OPI flash, flash read and write under DTR mode.

  enumerator SPI_FLASH_READ_MODE_MAX

    The fastest io mode supported by the host is `ESP_FLASH_READ_MODE_MAX-1`.

### Header File

- components/hal/include/hal/esp_flash_err.h

- This header file can be included with:

  >     #include "hal/esp_flash_err.h"

### Macros

ESP_ERR_FLASH_NOT_INITIALISED

  esp_flash_chip_t structure not correctly initialised by esp_flash_init().

ESP_ERR_FLASH_UNSUPPORTED_HOST

  Requested operation isn't supported via this host SPI bus (chip->spi field).

ESP_ERR_FLASH_UNSUPPORTED_CHIP

  Requested operation isn't supported by this model of SPI flash chip.

ESP_ERR_FLASH_PROTECTED

  Write operation failed due to chip's write protection being enabled.

### Header File

- components/spi_flash/include/esp_spi_flash_counters.h

- This header file can be included with:

  >     #include "esp_spi_flash_counters.h"

- This header file is a part of the API provided by the `spi_flash` component. To declare that your component depends on `spi_flash`, add the following to your CMakeLists.txt:

  >     REQUIRES spi_flash

  > or

  >     PRIV_REQUIRES spi_flash

### Functions

void esp_flash_reset_counters(void)

  Reset SPI flash operation counters.

void spi_flash_reset_counters(void)

void esp_flash_dump_counters(FILE *stream)

  Print SPI flash operation counters.

void spi_flash_dump_counters(void)

const esp_flash_counters_t *esp_flash_get_counters(void)

  Return current SPI flash operation counters.

  返回:

    pointer to the esp_flash_counters_t structure holding values of the operation counters

const spi_flash_counters_t *spi_flash_get_counters(void)

### Structures

struct esp_flash_counter_t

  Structure holding statistics for one type of operation

  Public Members

  uint32_t count

    number of times operation was executed

  uint32_t time

    total time taken, in microseconds

  uint32_t bytes

    total number of bytes

struct esp_flash_counters_t

  Structure for counters of flash actions

  Public Members

  esp_flash_counter_t read

    counters for read action, like `esp_flash_read`

  esp_flash_counter_t write

    counters for write action, like `esp_flash_write`

  esp_flash_counter_t erase

    counters for erase action, like `esp_flash_erase`

### Type Definitions

typedef esp_flash_counter_t spi_flash_counter_t

typedef esp_flash_counters_t spi_flash_counters_t

## flash 加密 API 参考

### Header File

- components/bootloader_support/include/esp_flash_encrypt.h

- This header file can be included with:

  >     #include "esp_flash_encrypt.h"

- This header file is a part of the API provided by the `bootloader_support` component. To declare that your component depends on `bootloader_support`, add the following to your CMakeLists.txt:

  >     REQUIRES bootloader_support

  > or

  >     PRIV_REQUIRES bootloader_support

### Functions

bool esp_flash_encryption_enabled(void)

  Is flash encryption currently enabled in hardware?

  Flash encryption is enabled if the FLASH_CRYPT_CNT efuse has an odd number of bits set.

  返回:

    true if flash encryption is enabled.

esp_err_t esp_flash_encrypt_check_and_update(void)

bool esp_flash_encrypt_state(void)

  Returns the Flash Encryption state and prints it.

  返回:

    True - Flash Encryption is enabled False - Flash Encryption is not enabled

bool esp_flash_encrypt_initialized_once(void)

  Checks if the first initialization was done.

  If the first initialization was done then FLASH_CRYPT_CNT != 0

  返回:

    true - the first initialization was done false - the first initialization was NOT done

esp_err_t esp_flash_encrypt_init(void)

  The first initialization of Flash Encryption key and related eFuses.

  返回:

    ESP_OK if all operations succeeded

esp_err_t esp_flash_encrypt_contents(void)

  Encrypts flash content.

  返回:

    ESP_OK if all operations succeeded

esp_err_t esp_flash_encrypt_enable(void)

  Activates Flash encryption on the chip.

  It burns FLASH_CRYPT_CNT eFuse based on the CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE option.

  返回:

    ESP_OK if all operations succeeded

bool esp_flash_encrypt_is_write_protected(bool print_error)

  Returns True if the write protection of FLASH_CRYPT_CNT is set.

  参数:

    print_error -- Print error if it is write protected

  返回:

    true - if FLASH_CRYPT_CNT is write protected

esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)

  Encrypt-in-place a block of flash sectors.

  备注

  This function resets RTC_WDT between operations with sectors.

  参数:

    - src_addr -- Source offset in flash. Should be multiple of 4096 bytes.

    - data_length -- Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.

  返回:

    ESP_OK if all operations succeeded, ESP_ERR_FLASH_OP_FAIL if SPI flash fails, ESP_ERR_FLASH_OP_TIMEOUT if flash times out.

void esp_flash_write_protect_crypt_cnt(void)

  Write protect FLASH_CRYPT_CNT.

  Intended to be called as a part of boot process if flash encryption is enabled but secure boot is not used. This should protect against serial re-flashing of an unauthorised code in absence of secure boot.

  备注

  On ESP32 V3 only, write protecting FLASH_CRYPT_CNT will also prevent disabling UART Download Mode. If both are wanted, call esp_efuse_disable_rom_download_mode() before calling this function.

esp_flash_enc_mode_t esp_get_flash_encryption_mode(void)

  Return the flash encryption mode.

  The API is called during boot process but can also be called by application to check the current flash encryption mode of ESP32

  返回:

void esp_flash_encryption_init_checks(void)

  Check the flash encryption mode during startup.

  Verifies the flash encryption config during startup:

  - Correct any insecure flash encryption settings if hardware Secure Boot is enabled.

  - Log warnings if the efuse config doesn't match the project config in any way

  备注

  This function is called automatically during app startup, it doesn't need to be called from the app.

bool esp_flash_encryption_cfg_verify_release_mode(void)

  Returns the verification status for all physical security features of flash encryption in release mode.

  If the device has flash encryption feature configured in the release mode, then it is highly recommended to call this API in the application startup code. This API verifies the sanity of the eFuse configuration against the release (production) mode of the flash encryption feature.

  返回:

    - True - all eFuses are configured correctly

    - False - not all eFuses are configured correctly.

void esp_flash_encryption_set_release_mode(void)

  Switches Flash Encryption from "Development" to "Release".

  If already in "Release" mode, the function will do nothing. If flash encryption efuse is not enabled yet then abort. It burns:

  - "disable encrypt in dl mode"

  - set FLASH_CRYPT_CNT efuse to max

  In case of the targets that support the XTS-AES peripheral's pseudo rounds function, this API would configure the pseudo rounds level efuse bit to level low if the efuse bit is not set already.

### Enumerations

enum esp_flash_enc_mode_t

  Values:

  enumerator ESP_FLASH_ENC_MODE_DISABLED
  enumerator ESP_FLASH_ENC_MODE_DEVELOPMENT
  enumerator ESP_FLASH_ENC_MODE_RELEASE

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。