refactor(spi_flash): reorganize header files and improve API encapsulation

This commit reorganizes SPI flash header files to better reflect their
visibility and intended usage:

1. Rename `esp_flash_port/` to `esp_flash_chips/`:
   - Better reflects that these headers are for chip driver implementations
   - All chip driver headers moved to `esp_flash_chips/` directory
   - Added README.md explaining semi-public nature of these headers

2. Move internal headers to `esp_private/`:
   - `esp_flash_internal.h` -> `esp_private/esp_flash_internal.h`
   - `memspi_host_driver.h` -> `esp_private/memspi_host_driver.h`

3. Move chip driver related headers to `esp_flash_chips/`:
   - `esp_private/esp_flash_types.h` -> `esp_flash_chips/esp_flash_types.h`
   - `spi_flash/spi_flash_defs.h` -> `esp_flash_chips/spi_flash_defs.h`
   - `spi_flash_override.h` -> `esp_flash_chips/spi_flash_override.h`
   - All `spi_flash_chip_*.h` headers moved to `esp_flash_chips/`

4. Code improvements:
   - Remove unused includes (e.g., `spi_flash_override.h` from `cache_utils.c`)
   - Use public API `esp_flash_get_size()` instead of direct member access
   - Add `esp_flash_is_quad_mode` to linker.lf for IRAM placement

5. Documentation updates:
   - Add README.md in `esp_flash_chips/` explaining semi-public headers
   - Update programming guide with warnings about internal headers
   - Update both English and Chinese documentation

6. Update all references across the codebase:
   - Update includes in `spi_flash` component
   - Update `bootloader_support`, `app_update`, `esp_tee`, `espcoredump`
   - Update example projects

Breaking changes:
- Headers moved to new locations require include path updates
- `custom_flash_driver` example temporarily disabled until external
  components are updated
This commit is contained in:
Xiao Xufeng
2026-01-23 03:38:54 +08:00
parent 758cf6e1a3
commit 8dbf23630a
82 changed files with 375 additions and 219 deletions
@@ -0,0 +1,133 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include <stdint.h>
#include <stdbool.h>
#include "esp_private/spi_share_hw_ctrl.h"
#include "sdkconfig.h"
#include "esp_flash.h"
#include "esp_flash_chips/esp_flash_types.h"
/** Internal API, don't use in the applications */
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Initialise the default SPI flash chip
*
* Called by OS startup code. You do not need to call this in your own applications.
*/
esp_err_t esp_flash_init_default_chip(void);
/**
* Enable OS-level SPI flash protections in IDF
*
* Called by OS startup code. You do not need to call this in your own applications.
*
* @return ESP_OK if success, otherwise failed. See return value of ``esp_flash_init_os_functions``.
*/
esp_err_t esp_flash_app_init(void);
/**
* Disable (or enable) OS-level SPI flash protections in IDF
*
* Called by the IDF internal code (e.g. coredump). You do not need to call this in your own applications.
*
* @return always ESP_OK.
*/
esp_err_t esp_flash_app_disable_protect(bool disable);
/**
* Initialize OS-level functions for a specific chip.
*
* @param chip The chip to init os functions.
* @param host_id Which SPI host to use, 1 for SPI1, 2 for SPI2 (HSPI), 3 for SPI3 (VSPI)
* @param dev_handle SPI bus lock device handle to acquire during flash operations
*
* @return
* - ESP_OK if success
* - ESP_ERR_INVALID_ARG if host_id is invalid
*/
esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id, spi_bus_lock_dev_handle_t dev_handle);
/**
* @brief Deinitialize OS-level functions
*
* @param chip The chip to deinit os functions
* @param out_dev_handle The SPI bus lock passed from `esp_flash_init_os_functions`. The caller should deinitialize
* the lock.
* @return always ESP_OK.
*/
esp_err_t esp_flash_deinit_os_functions(esp_flash_t* chip, spi_bus_lock_dev_handle_t* out_dev_handle);
/**
* @brief Initialize the bus lock on the SPI1 bus. Should be called if drivers (including esp_flash)
* wants to use SPI1 bus.
*
* @note When using legacy spi flash API, the bus lock will not be available on SPI1 bus.
*
* @return esp_err_t always ESP_OK.
*/
esp_err_t esp_flash_init_main_bus_lock(void);
/**
* Initialize OS-level functions for the main flash chip.
*
* @param chip The chip to init os functions. Only pointer to the default chip is supported now.
*
* @return always ESP_OK
*/
esp_err_t esp_flash_app_enable_os_functions(esp_flash_t* chip);
/**
* Disable OS-level functions for the main flash chip during special phases (e.g. coredump)
*
* @param chip The chip to init os functions. Only "esp_flash_default_chip" is supported now.
*
* @return always ESP_OK
*/
esp_err_t esp_flash_app_disable_os_functions(esp_flash_t* chip);
/**
* @brief Set or clear dangerous write protection check on the flash chip.
*
* This function sets the runtime option to allow or disallow writing to
* dangerous areas such as the bootloader and partition table. If
* CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set, this function allows
* the caller to toggle the protection for specific areas.
*
* If CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is set, there is no protection
* check in the system, and this function does nothing.
*
* @param chip The flash chip on which to set the write protection. Only
* "esp_flash_default_chip" is supported.
* @param protect Set to true to enable protection against writing in dangerous
* areas (bootloader, partition table). Set to false to disable
* the protection.
* @return
* - ESP_OK: Successful operation.
* - ESP_ERR_INVALID_ARG: The chip argument is null.
*/
esp_err_t esp_flash_set_dangerous_write_protection(esp_flash_t *chip, const bool protect);
#if CONFIG_SPI_FLASH_ROM_IMPL
/**
* @brief Initialize ROM API functions structure
*
* This function initializes the ROM API functions structure, either by pointing
* to a custom structure or by patching the ROM structure in RAM.
*/
void esp_flash_rom_api_funcs_init(void);
#endif // CONFIG_SPI_FLASH_ROM_IMPL
#ifdef __cplusplus
}
#endif
@@ -1,101 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include <stdint.h>
#include <stdbool.h>
#include "esp_bit_defs.h"
#include "hal/spi_flash_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct spi_flash_chip_t;
typedef struct spi_flash_chip_t spi_flash_chip_t;
/** @brief OS-level integration hooks for accessing flash chips inside a running OS
*
* This structure is used internally by the SPI flash driver and should not be used directly by applications.
* It's defined here because some instances need to be allocated statically in the startup code.
*/
typedef struct esp_flash_os_functions_t {
/**
* Flags for start function
*/
/** Limit CPU frequency during flash operations (ESP32-C5 only, 240MHz).
*/
#define ESP_FLASH_START_FLAG_LIMIT_CPU_FREQ BIT(0)
/**
* 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 (*start)(void *arg, uint32_t flags);
/** Called after completing any flash operation. */
esp_err_t (*end)(void *arg);
/** Called before any erase/write operations to check whether the region is limited by the OS */
esp_err_t (*region_protected)(void* arg, size_t start_addr, size_t size);
/** Delay for at least 'us' microseconds. Called in between 'start' and 'end'. */
esp_err_t (*delay_us)(void *arg, uint32_t us);
/** Called for get temp buffer when buffer from application cannot be directly read into/write from. */
void *(*get_temp_buffer)(void* arg, size_t reqest_size, size_t* out_size);
/** Called for release temp buffer. */
void (*release_temp_buffer)(void *arg, void *temp_buf);
#define SPI_FLASH_YIELD_REQ_YIELD BIT(0)
#define SPI_FLASH_YIELD_REQ_SUSPEND BIT(1)
/** 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 (*check_yield)(void *arg, uint32_t chip_status, uint32_t* out_request);
#define SPI_FLASH_YIELD_STA_RESUME BIT(2)
/** Yield to other tasks. Called during erase operations. */
esp_err_t (*yield)(void *arg, uint32_t* out_status);
/** Called for get system time. */
int64_t (*get_system_time)(void *arg);
#define SPI_FLASH_OS_IS_ERASING_STATUS_FLAG BIT(0)
/** Call to set flash operation status */
void (*set_flash_op_status)(uint32_t op_status);
} esp_flash_os_functions_t;
/** @brief Structure to describe a SPI flash chip connected to the system.
*
* This structure is used internally by the SPI flash driver and should not be used directly by applications.
* It's defined here because some instances need to be allocated statically in the startup code.
*/
struct esp_flash_t {
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 :1; ///< This flag is used to verify chip's status.
uint32_t hpm_dummy_ena :1; ///< This flag is used to verify whether flash works under HPM status.
uint32_t reserved_flags :30; ///< reserved.
int clock_source; ///< Clock source for GPSPI.
};
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,193 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "hal/spi_flash_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Default configuration for the memspi (high speed version) */
#define ESP_FLASH_DEFAULT_HOST_DRIVER() (spi_flash_host_driver_t) { \
.dev_config = spi_flash_hal_device_config, \
.common_command = spi_flash_hal_common_command, \
.read_id = memspi_host_read_id_hs, \
.erase_chip = spi_flash_hal_erase_chip, \
.erase_sector = spi_flash_hal_erase_sector, \
.erase_block = spi_flash_hal_erase_block, \
.read_status = memspi_host_read_status_hs, \
.set_write_protect = spi_flash_hal_set_write_protect, \
.supports_direct_write = spi_flash_hal_supports_direct_write, \
.supports_direct_read = spi_flash_hal_supports_direct_read, \
.program_page = spi_flash_hal_program_page, \
.write_data_slicer = memspi_host_write_data_slicer, \
.read = spi_flash_hal_read, \
.read_data_slicer = memspi_host_read_data_slicer, \
.host_status = spi_flash_hal_check_status, \
.configure_host_io_mode = spi_flash_hal_configure_host_io_mode, \
.poll_cmd_done = spi_flash_hal_poll_cmd_done, \
.flush_cache = memspi_host_flush_cache, \
.check_suspend = NULL, \
.resume = spi_flash_hal_resume, \
.suspend = spi_flash_hal_suspend,\
.sus_setup = spi_flash_hal_setup_read_suspend,\
}
/// configuration for the memspi host
typedef spi_flash_hal_config_t memspi_host_config_t;
/// context for the memspi host
typedef spi_flash_hal_context_t memspi_host_inst_t;
/**
* Initialize the memory SPI host.
*
* @param host Pointer to the host structure.
* @param cfg Pointer to configuration structure
*
* @return always return ESP_OK
*/
esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_config_t *cfg);
/**
* Initialize the memory SPI host for ESP32-C5 dynamic configuration.
*
* @param host Pointer to the host structure.
*
* @note This function is available only when CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ is defined.
* @note This function can only be called once at startup, after memspi_host_init_pointers() is called.
* @return always return ESP_OK
*/
esp_err_t memspi_host_init_c5_dynamic_config(memspi_host_inst_t *host);
/*******************************************************************************
* NOTICE
* Rest part of this file are part of the HAL layer
* The HAL is not public api, don't use in application code.
* See readme.md in hal/include/hal/readme.md
******************************************************************************/
/**
* @brief Read the Status Register read from RDSR (05h).
*
* High speed implementation of RDID through memspi interface relying on the
* ``common_command``.
*
* @param host The driver context.
* @param id Output of the read ID from the slave.
*
* @return
* - ESP_OK: if success
* - ESP_ERR_FLASH_NO_RESPONSE: if no response from chip
* - or other cases from ``spi_hal_common_command``
*/
esp_err_t memspi_host_read_id_hs(spi_flash_host_inst_t *host, uint32_t *id);
/**
* High speed implementation of RDSR through memspi interface relying on the
* ``common_command``.
*
* @param host The driver context.
* @param id Output of the read ID from the slave.
*
* @return
* - ESP_OK: if success
* - or other cases from ``spi_hal_common_command``
*/
esp_err_t memspi_host_read_status_hs(spi_flash_host_inst_t *host, uint8_t *out_sr);
/**
* Flush the cache (if needed) after the contents are modified.
*
* @param host The driver context.
* @param addr Start address of the modified region
* @param size Size of the region modified.
*
* @return always ESP_OK.
*/
esp_err_t memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size);
/**
* Erase contents of entire chip.
*
* @param host The driver context.
*/
void memspi_host_erase_chip(spi_flash_host_inst_t *host);
/**
* Erase a sector starting from a given address. For 24bit address only.
*
* @param host The driver context.
* @param start_address Starting address of the sector.
*/
void memspi_host_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Erase a block starting from a given address. For 24bit address only.
*
* @param host The driver context.
* @param start_address Starting address of the block.
*/
void memspi_host_erase_block(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Program a page with contents of a buffer. For 24bit address only.
*
* @param host The driver context.
* @param buffer Buffer which contains the data to be flashed.
* @param address Starting address of where to flash the data.
* @param length The number of bytes to flash.
*/
void memspi_host_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
/**
* Set ability to write to chip.
*
* @param host The driver context.
* @param wp Enable or disable write protect (true - enable, false - disable).
*/
esp_err_t memspi_host_set_write_protect(spi_flash_host_inst_t *host, bool wp);
/**
* Read data to buffer.
*
* @param host The driver context.
* @param buffer Buffer which contains the data to be read.
* @param address Starting address of where to read the data.
* @param length The number of bytes to read.
*/
esp_err_t memspi_host_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
/**
* @brief Slicer for read data used in non-encrypted regions. This slicer does nothing but
* limit the length to the maximum size the host supports.
*
* @param address Flash address to read
* @param len Length to read
* @param align_address Output of the address to read, should be equal to the input `address`
* @param page_size Physical SPI flash page size
*
* @return Length that can actually be read in one `read` call in `spi_flash_host_driver_t`.
*/
int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);
/**
* @brief Slicer for write data used in non-encrypted regions. This slicer limit the length to the
* maximum size the host supports, and truncate if the write data lie across the page boundary
* (256 bytes)
*
* @param address Flash address to write
* @param len Length to write
* @param align_address Output of the address to write, should be equal to the input `address`
* @param page_size Physical SPI flash page size
*
* @return Length that can actually be written in one `program_page` call in `spi_flash_host_driver_t`.
*/
int memspi_host_write_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);
#ifdef __cplusplus
}
#endif
@@ -14,13 +14,15 @@
#include "sdkconfig.h"
#include "esp_rom_spiflash.h"
#include "esp_err.h"
#include "esp_flash.h"
#include "esp_private/esp_flash_types.h"
#include "hal/spi_flash_hal.h"
#include "spi_flash_override.h"
#include "soc/soc_caps.h"
#include "soc/clk_tree_defs.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_flash_chips/esp_flash_types.h"
#include "esp_flash_chips/spi_flash_override.h"
#ifdef __cplusplus
extern "C" {
#endif