SPI Flash APIs

Overview

The spi_flash component contains APIs related to reading, writing, erasing, memory mapping data in the external SPI flash. It also has higher-level APIs which work with partitions defined in the partition table.

Note that all the functionality is limited to the “main” SPI flash chip, the same SPI flash chip from which program runs. For spi_flash_* functions, this is a software limitation. The underlying ROM functions which work with SPI flash do not have provisions for working with flash chips attached to SPI peripherals other than SPI0.

SPI flash access APIs

This is the set of APIs for working with data in flash:

Generally, try to avoid using the raw SPI flash functions in favour of partition-specific functions.

SPI Flash Size

The SPI flash size is configured by writing a field in the software bootloader image header, flashed at offset 0x1000.

By default, the SPI flash size is detected by esptool.py when this bootloader is written to flash, and the header is updated with the correct size. Alternatively, it is possible to generate a fixed flash size by setting CONFIG_ESPTOOLPY_FLASHSIZE in make menuconfig.

If it is necessary to override the configured flash size at runtime, is is possible to set the chip_size member of g_rom_flashchip structure. This size is used by spi_flash_* functions (in both software & ROM) for bounds checking.

Concurrency Constraints

Because the SPI flash is also used for firmware execution (via the instruction & data caches), these caches must be disabled while reading/writing/erasing. This means that both CPUs must be running code from IRAM and only reading data from DRAM while flash write operations occur.

If you use the APIs documented here, then this happens automatically and transparently. However note that it will have some performance impact on other tasks in the system.

Refer to the application memory layout documentation for an explanation of the differences between IRAM, DRAM and flash cache.

To avoid reading flash cache accidentally, when one CPU commences a flash write or erase operation the other CPU is put into a blocked state and all non-IRAM-safe interrupts are disabled on both CPUs, until the flash operation completes.

IRAM-Safe Interrupt Handlers

If you have an interrupt handler that you want to execute even when a flash operation is in progress (for example, for low latency operations), set the ESP_INTR_FLAG_IRAM flag when the interrupt handler is registered.

You must ensure all data and functions accessed by these interrupt handlers are located in IRAM or DRAM. This includes any functions that the handler calls.

Use the IRAM_ATTR attribute for functions:

#include "esp_attr.h"

void IRAM_ATTR gpio_isr_handler(void* arg)
{
    // ...
}

Use the DRAM_ATTR and DRAM_STR attributes for constant data:

void IRAM_ATTR gpio_isr_handler(void* arg)
{
   const static DRAM_ATTR uint8_t INDEX_DATA[] = { 45, 33, 12, 0 };
   const static char *MSG = DRAM_STR("I am a string stored in RAM");
}

Note that knowing which data should be marked with DRAM_ATTR can be hard, the compiler will sometimes recognise that a variable or expression is constant (even if it is not marked const) and optimise it into flash, unless it is marked with DRAM_ATTR.

If a function or symbol is not correctly put into IRAM/DRAM and the interrupt handler reads from the flash cache during a flash operation, it will cause a crash due to Illegal Instruction exception (for code which should be in IRAM) or garbage data to be read (for constant data which should be in DRAM).

Partition table APIs

ESP-IDF projects use a partition table to maintain information about various regions of SPI flash memory (bootloader, various application binaries, data, filesystems). More information about partition tables can be found here.

This component provides APIs to enumerate partitions found in the partition table and perform operations on them. These functions are declared in esp_partition.h:

Note

Most application code should use these esp_partition_* APIs instead of lower level spi_flash_* APIs. Partition APIs do bounds checking and calculate correct offsets in flash based on data stored in partition table.

SPI Flash Encryption

It is possible to encrypt SPI flash contents, and have it transparenlty decrypted by hardware.

Refer to the Flash Encryption documentation for more details.

Memory mapping APIs

ESP32 features memory hardware which allows regions of flash memory to be mapped into instruction and data address spaces. This mapping works only for read operations, it is not possible to modify contents of flash memory by writing to mapped memory region. Mapping happens in 64KB pages. Memory mapping hardware can map up to 4 megabytes of flash into data address space, and up to 16 megabytes of flash into instruction address space. See the technical reference manual for more details about memory mapping hardware.

Note that some number of 64KB pages is used to map the application itself into memory, so the actual number of available 64KB pages may be less.

Reading data from flash using a memory mapped region is the only way to decrypt contents of flash when flash encryption is enabled. Decryption is performed at hardware level.

Memory mapping APIs are declared in esp_spi_flash.h and esp_partition.h:

Differences between spi_flash_mmap() and esp_partition_mmap() are as follows:

  • spi_flash_mmap() must be given a 64KB aligned physical address

  • esp_partition_mmap() may be given any arbitrary offset within the partition, it will adjust returned pointer to mapped memory as necessary

Note that because memory mapping happens in 64KB blocks, it may be possible to read data outside of the partition provided to esp_partition_mmap.

See also

Implementation details

In order to perform some flash operations, we need to make sure both CPUs are not running any code from flash for the duration of the flash operation. In a single-core setup this is easy: we disable interrupts/scheduler and do the flash operation. In the dual-core setup this is slightly more complicated. We need to make sure that the other CPU doesn’t run any code from flash.

When SPI flash API is called on CPU A (can be PRO or APP), we start spi_flash_op_block_func function on CPU B using esp_ipc_call API. This API wakes up high priority task on CPU B and tells it to execute given function, in this case spi_flash_op_block_func. This function disables cache on CPU B and signals that cache is disabled by setting s_flash_op_can_start flag. Then the task on CPU A disables cache as well, and proceeds to execute flash operation.

While flash operation is running, interrupts can still run on CPUs A and B. We assume that all interrupt code is placed into RAM. Once interrupt allocation API is added, we should add a flag to request interrupt to be disabled for the duration of flash operations.

Once flash operation is complete, function on CPU A sets another flag, s_flash_op_complete, to let the task on CPU B know that it can re-enable cache and release the CPU. Then the function on CPU A re-enables the cache on CPU A as well and returns control to the calling code.

Additionally, all API functions are protected with a mutex (s_flash_op_mutex).

In a single core environment (CONFIG_FREERTOS_UNICORE enabled), we simply disable both caches, no inter-CPU communication takes place.

API Reference - SPI Flash

Functions

void spi_flash_init()

Initialize SPI flash access driver.

This function must be called exactly once, before any other spi_flash_* functions are called. Currently this function is called from startup code. There is no need to call it from application code.

size_t spi_flash_get_chip_size()

Get flash chip size, as set in binary image header.

Note

This value does not necessarily match real flash size.

Return

size of flash chip, in bytes

esp_err_t spi_flash_erase_sector(size_t sector)

Erase the Flash sector.

Return

esp_err_t

Parameters
  • sector: Sector number, the count starts at sector 0, 4KB per sector.

esp_err_t spi_flash_erase_range(size_t start_address, size_t size)

Erase a range of flash sectors.

Return

esp_err_t

Parameters
  • start_address: Address where erase operation has to start. Must be 4kB-aligned

  • size: Size of erased range, in bytes. Must be divisible by 4kB.

esp_err_t spi_flash_write(size_t dest_addr, const void *src, size_t size)

Write data to Flash.

Note

For fastest write performance, write a 4 byte aligned size at a 4 byte aligned offset in flash from a source buffer in DRAM. Varying any of these parameters will still work, but will be slower due to buffering.

Note

Writing more than 8KB at a time will be split into multiple write operations to avoid disrupting other tasks in the system.

Return

esp_err_t

Parameters
  • dest_addr: Destination address in Flash.

  • src: Pointer to the source buffer.

  • size: Length of data, in bytes.

esp_err_t spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size)

Write data encrypted to Flash.

Note

Flash encryption must be enabled for this function to work.

Note

Flash encryption must be enabled when calling this function. If flash encryption is disabled, the function returns ESP_ERR_INVALID_STATE. Use esp_flash_encryption_enabled() function to determine if flash encryption is enabled.

Note

Both dest_addr and size must be multiples of 16 bytes. For absolute best performance, both dest_addr and size arguments should be multiples of 32 bytes.

Return

esp_err_t

Parameters
  • dest_addr: Destination address in Flash. Must be a multiple of 16 bytes.

  • src: Pointer to the source buffer.

  • size: Length of data, in bytes. Must be a multiple of 16 bytes.

esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size)

Read data from Flash.

Note

For fastest read performance, all parameters should be 4 byte aligned. If source address and read size are not 4 byte aligned, read may be split into multiple flash operations. If destination buffer is not 4 byte aligned, a temporary buffer will be allocated on the stack.

Note

Reading more than 16KB of data at a time will be split into multiple reads to avoid disruption to other tasks in the system. Consider using spi_flash_mmap() to read large amounts of data.

Return

esp_err_t

Parameters
  • src_addr: source address of the data in Flash.

  • dest: pointer to the destination buffer

  • size: length of data

esp_err_t spi_flash_read_encrypted(size_t src, void *dest, size_t size)

Read data from Encrypted Flash.

If flash encryption is enabled, this function will transparently decrypt data as it is read. If flash encryption is not enabled, this function behaves the same as spi_flash_read().

See esp_flash_encryption_enabled() for a function to check if flash encryption is enabled.

Return

esp_err_t

Parameters
  • src: source address of the data in Flash.

  • dest: pointer to the destination buffer

  • size: length of data

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.

Return

ESP_OK on success, ESP_ERR_NO_MEM if pages can not be allocated

Parameters
  • 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] out_ptr: Output, pointer to the mapped memory region

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

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.

Return

  • 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

Parameters
  • 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] out_ptr: Output, pointer to the mapped memory region

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

void spi_flash_munmap(spi_flash_mmap_handle_t handle)

Release region previously obtained using spi_flash_mmap.

Note

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.

Parameters
  • handle: Handle obtained from spi_flash_mmap

void spi_flash_mmap_dump()

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.

Return

number of free pages which can be mmaped

Parameters
  • memory: memory type of MMU table free page

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.

Return

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

  • Otherwise, returns physical offset in flash

Parameters
  • cached: Pointer to flashed cached memory.

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.

Note

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.

Note

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.

Return

  • 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.

Parameters
  • 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)

bool spi_flash_cache_enabled()

Check at runtime if flash cache is enabled on both CPUs.

Return

true if both CPUs have flash cache enabled, false otherwise.

void spi_flash_guard_set(const spi_flash_guard_funcs_t *funcs)

Sets guard functions to access flash.

Note

Pointed structure and corresponding guard functions should not reside in flash. For example structure can be placed in DRAM and functions in IRAM sections.

Parameters
  • funcs: pointer to structure holding flash access guard functions.

const spi_flash_guard_funcs_t *spi_flash_guard_get()

Get the guard functions used for flash access.

Return

The guard functions that were set via spi_flash_guard_set(). These functions can be called if implementing custom low-level SPI flash operations.

Structures

struct spi_flash_guard_funcs_t

Structure holding SPI flash access critical sections management functions.

Flash API uses two types of flash access management functions: 1) Functions which prepare/restore flash cache and interrupts before calling appropriate ROM functions (SPIWrite, SPIRead and SPIEraseBlock):

  • ’start’ function should disables flash cache and non-IRAM interrupts and is invoked before the call to one of ROM function above.

  • ’end’ function should restore state of flash cache and non-IRAM interrupts and is invoked after the call to one of ROM function above. These two functions are not recursive. 2) Functions which synchronizes access to internal data used by flash API. This functions are mostly intended to synchronize access to flash API internal data in multithreaded environment and use OS primitives:

  • ’op_lock’ locks access to flash API internal data.

  • ’op_unlock’ unlocks access to flash API internal data. These two functions are recursive and can be used around the outside of multiple calls to ‘start’ & ‘end’, in order to create atomic multi-part flash operations. 3) When CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is disabled, flash writing/erasing API checks for addresses provided by user to avoid corruption of critical flash regions (bootloader, partition table, running application etc.).

Different versions of the guarding functions should be used depending on the context of execution (with or without functional OS). In normal conditions when flash API is called from task the functions use OS primitives. When there is no OS at all or when it is not guaranteed that OS is functional (accessing flash from exception handler) these functions cannot use OS primitives or even does not need them (multithreaded access is not possible).

Note

Structure and corresponding guard functions should not reside in flash. For example structure can be placed in DRAM and functions in IRAM sections.

Public Members

spi_flash_guard_start_func_t start

critical section start function.

spi_flash_guard_end_func_t end

critical section end function.

spi_flash_op_lock_func_t op_lock

flash access API lock function.

spi_flash_op_unlock_func_t op_unlock

flash access API unlock function.

spi_flash_is_safe_write_address_t is_safe_write_address

checks flash write addresses.

spi_flash_os_yield_t yield

yield to the OS during flash erase

Macros

ESP_ERR_FLASH_BASE
ESP_ERR_FLASH_OP_FAIL
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.

typedef void (*spi_flash_guard_start_func_t)(void)

SPI flash critical section enter function.

typedef void (*spi_flash_guard_end_func_t)(void)

SPI flash critical section exit function.

typedef void (*spi_flash_op_lock_func_t)(void)

SPI flash operation lock function.

typedef void (*spi_flash_op_unlock_func_t)(void)

SPI flash operation unlock function.

typedef bool (*spi_flash_is_safe_write_address_t)(size_t addr, size_t size)

Function to protect SPI flash critical regions corruption.

typedef void (*spi_flash_os_yield_t)(void)

Function to yield to the OS during erase operation.

Enumerations

enum spi_flash_mmap_memory_t

Enumeration which specifies memory space requested in an mmap call.

Values:

SPI_FLASH_MMAP_DATA

map to data memory (Vaddr0), allows byte-aligned access, 4 MB total

SPI_FLASH_MMAP_INST

map to instruction memory (Vaddr1-3), allows only 4-byte-aligned access, 11 MB total

API Reference - Partition Table

Functions

esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, esp_partition_subtype_t subtype, const char *label)

Find partition based on one or more parameters.

Return

iterator which can be used to enumerate all the partitions found, or NULL if no partitions were found. Iterator obtained through this function has to be released using esp_partition_iterator_release when not used any more.

Parameters
  • type: Partition type, one of esp_partition_type_t values

  • subtype: Partition subtype, one of esp_partition_subtype_t values. To find all partitions of given type, use ESP_PARTITION_SUBTYPE_ANY.

  • label: (optional) Partition label. Set this value if looking for partition with a specific name. Pass NULL otherwise.

const esp_partition_t *esp_partition_find_first(esp_partition_type_t type, esp_partition_subtype_t subtype, const char *label)

Find first partition based on one or more parameters.

Return

pointer to esp_partition_t structure, or NULL if no partition is found. This pointer is valid for the lifetime of the application.

Parameters
  • type: Partition type, one of esp_partition_type_t values

  • subtype: Partition subtype, one of esp_partition_subtype_t values. To find all partitions of given type, use ESP_PARTITION_SUBTYPE_ANY.

  • label: (optional) Partition label. Set this value if looking for partition with a specific name. Pass NULL otherwise.

const esp_partition_t *esp_partition_get(esp_partition_iterator_t iterator)

Get esp_partition_t structure for given partition.

Return

pointer to esp_partition_t structure. This pointer is valid for the lifetime of the application.

Parameters
  • iterator: Iterator obtained using esp_partition_find. Must be non-NULL.

esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t iterator)

Move partition iterator to the next partition found.

Any copies of the iterator will be invalid after this call.

Return

NULL if no partition was found, valid esp_partition_iterator_t otherwise.

Parameters
  • iterator: Iterator obtained using esp_partition_find. Must be non-NULL.

void esp_partition_iterator_release(esp_partition_iterator_t iterator)

Release partition iterator.

Parameters
  • iterator: Iterator obtained using esp_partition_find. Must be non-NULL.

const esp_partition_t *esp_partition_verify(const esp_partition_t *partition)

Verify partition data.

Given a pointer to partition data, verify this partition exists in the partition table (all fields match.)

This function is also useful to take partition data which may be in a RAM buffer and convert it to a pointer to the permanent partition data stored in flash.

Pointers returned from this function can be compared directly to the address of any pointer returned from esp_partition_get(), as a test for equality.

Return

  • If partition not found, returns NULL.

  • If found, returns a pointer to the esp_partition_t structure in flash. This pointer is always valid for the lifetime of the application.

Parameters
  • partition: Pointer to partition data to verify. Must be non-NULL. All fields of this structure must match the partition table entry in flash for this function to return a successful match.

esp_err_t esp_partition_read(const esp_partition_t *partition, size_t src_offset, void *dst, size_t size)

Read data from the partition.

Return

ESP_OK, if data was read successfully; ESP_ERR_INVALID_ARG, if src_offset exceeds partition size; ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition; or one of error codes from lower-level flash driver.

Parameters
  • partition: Pointer to partition structure obtained using esp_partition_find_first or esp_partition_get. Must be non-NULL.

  • dst: Pointer to the buffer where data should be stored. Pointer must be non-NULL and buffer must be at least ‘size’ bytes long.

  • src_offset: Address of the data to be read, relative to the beginning of the partition.

  • size: Size of data to be read, in bytes.

esp_err_t esp_partition_write(const esp_partition_t *partition, size_t dst_offset, const void *src, size_t size)

Write data to the partition.

Before writing data to flash, corresponding region of flash needs to be erased. This can be done using esp_partition_erase_range function.

Partitions marked with an encryption flag will automatically be written via the spi_flash_write_encrypted() function. If writing to an encrypted partition, all write offsets and lengths must be multiples of 16 bytes. See the spi_flash_write_encrypted() function for more details. Unencrypted partitions do not have this restriction.

Note

Prior to writing to flash memory, make sure it has been erased with esp_partition_erase_range call.

Return

ESP_OK, if data was written successfully; ESP_ERR_INVALID_ARG, if dst_offset exceeds partition size; ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition; or one of error codes from lower-level flash driver.

Parameters
  • partition: Pointer to partition structure obtained using esp_partition_find_first or esp_partition_get. Must be non-NULL.

  • dst_offset: Address where the data should be written, relative to the beginning of the partition.

  • src: Pointer to the source buffer. Pointer must be non-NULL and buffer must be at least ‘size’ bytes long.

  • size: Size of data to be written, in bytes.

esp_err_t esp_partition_erase_range(const esp_partition_t *partition, uint32_t start_addr, uint32_t size)

Erase part of the partition.

Return

ESP_OK, if the range was erased successfully; ESP_ERR_INVALID_ARG, if iterator or dst are NULL; ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition; or one of error codes from lower-level flash driver.

Parameters
  • partition: Pointer to partition structure obtained using esp_partition_find_first or esp_partition_get. Must be non-NULL.

  • start_addr: Address where erase operation should start. Must be aligned to 4 kilobytes.

  • size: Size of the range which should be erased, in bytes. Must be divisible by 4 kilobytes.

esp_err_t esp_partition_mmap(const esp_partition_t *partition, uint32_t offset, uint32_t size, spi_flash_mmap_memory_t memory, const void **out_ptr, spi_flash_mmap_handle_t *out_handle)

Configure MMU to map partition into data memory.

Unlike spi_flash_mmap function, which requires a 64kB aligned base address, this function doesn’t impose such a requirement. If offset results in a flash address which is not aligned to 64kB boundary, address will be rounded to the lower 64kB boundary, so that mapped region includes requested range. Pointer returned via out_ptr argument will be adjusted to point to the requested offset (not necessarily to the beginning of mmap-ed region).

To release mapped memory, pass handle returned via out_handle argument to spi_flash_munmap function.

Return

ESP_OK, if successful

Parameters
  • partition: Pointer to partition structure obtained using esp_partition_find_first or esp_partition_get. Must be non-NULL.

  • offset: Offset from the beginning of partition where mapping should start.

  • size: Size of the area to be mapped.

  • memory: Memory space where the region should be mapped

  • out_ptr: Output, pointer to the mapped memory region

  • out_handle: Output, handle which should be used for spi_flash_munmap call

esp_err_t esp_partition_get_sha256(const esp_partition_t *partition, uint8_t *sha_256)

Get SHA-256 digest for required partition.

For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content. The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID. For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image. For other partition types, the result is the SHA-256 of the entire partition.

Return

  • ESP_OK: In case of successful operation.

  • ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.

  • ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.

  • ESP_ERR_IMAGE_INVALID: App partition doesn’t contain a valid app image.

  • ESP_FAIL: An allocation error occurred.

Parameters
  • [in] partition: Pointer to info for partition containing app or data. (fields: address, size and type, are required to be filled).

  • [out] sha_256: Returned SHA-256 digest for a given partition.

bool esp_partition_check_identity(const esp_partition_t *partition_1, const esp_partition_t *partition_2)

Check for the identity of two partitions by SHA-256 digest.

Return

  • True: In case of the two firmware is equal.

  • False: Otherwise

Parameters
  • [in] partition_1: Pointer to info for partition 1 containing app or data. (fields: address, size and type, are required to be filled).

  • [in] partition_2: Pointer to info for partition 2 containing app or data. (fields: address, size and type, are required to be filled).

Structures

struct esp_partition_t

partition information structure

This is not the format in flash, that format is esp_partition_info_t.

However, this is the format used by this API.

Public Members

esp_partition_type_t type

partition type (app/data)

esp_partition_subtype_t subtype

partition subtype

uint32_t address

starting address of the partition in flash

uint32_t size

size of the partition, in bytes

char label[17]

partition label, zero-terminated ASCII string

bool encrypted

flag is set to true if partition is encrypted

Macros

ESP_PARTITION_SUBTYPE_OTA(i)

Convenience macro to get esp_partition_subtype_t value for the i-th OTA partition.

Type Definitions

typedef struct esp_partition_iterator_opaque_ *esp_partition_iterator_t

Opaque partition iterator type.

Enumerations

enum esp_partition_type_t

Partition type.

Note

Keep this enum in sync with PartitionDefinition class gen_esp32part.py

Values:

ESP_PARTITION_TYPE_APP = 0x00

Application partition type.

ESP_PARTITION_TYPE_DATA = 0x01

Data partition type.

enum esp_partition_subtype_t

Partition subtype.

Note

Keep this enum in sync with PartitionDefinition class gen_esp32part.py

Values:

ESP_PARTITION_SUBTYPE_APP_FACTORY = 0x00

Factory application partition.

ESP_PARTITION_SUBTYPE_APP_OTA_MIN = 0x10

Base for OTA partition subtypes.

ESP_PARTITION_SUBTYPE_APP_OTA_0 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 0

OTA partition 0.

ESP_PARTITION_SUBTYPE_APP_OTA_1 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 1

OTA partition 1.

ESP_PARTITION_SUBTYPE_APP_OTA_2 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 2

OTA partition 2.

ESP_PARTITION_SUBTYPE_APP_OTA_3 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 3

OTA partition 3.

ESP_PARTITION_SUBTYPE_APP_OTA_4 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 4

OTA partition 4.

ESP_PARTITION_SUBTYPE_APP_OTA_5 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 5

OTA partition 5.

ESP_PARTITION_SUBTYPE_APP_OTA_6 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 6

OTA partition 6.

ESP_PARTITION_SUBTYPE_APP_OTA_7 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 7

OTA partition 7.

ESP_PARTITION_SUBTYPE_APP_OTA_8 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 8

OTA partition 8.

ESP_PARTITION_SUBTYPE_APP_OTA_9 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 9

OTA partition 9.

ESP_PARTITION_SUBTYPE_APP_OTA_10 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 10

OTA partition 10.

ESP_PARTITION_SUBTYPE_APP_OTA_11 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 11

OTA partition 11.

ESP_PARTITION_SUBTYPE_APP_OTA_12 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 12

OTA partition 12.

ESP_PARTITION_SUBTYPE_APP_OTA_13 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 13

OTA partition 13.

ESP_PARTITION_SUBTYPE_APP_OTA_14 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 14

OTA partition 14.

ESP_PARTITION_SUBTYPE_APP_OTA_15 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 15

OTA partition 15.

ESP_PARTITION_SUBTYPE_APP_OTA_MAX = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 16

Max subtype of OTA partition.

ESP_PARTITION_SUBTYPE_APP_TEST = 0x20

Test application partition.

ESP_PARTITION_SUBTYPE_DATA_OTA = 0x00

OTA selection partition.

ESP_PARTITION_SUBTYPE_DATA_PHY = 0x01

PHY init data partition.

ESP_PARTITION_SUBTYPE_DATA_NVS = 0x02

NVS partition.

ESP_PARTITION_SUBTYPE_DATA_COREDUMP = 0x03

COREDUMP partition.

ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS = 0x04

Partition for NVS keys.

ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM = 0x05

Partition for emulate eFuse bits.

ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD = 0x80

ESPHTTPD partition.

ESP_PARTITION_SUBTYPE_DATA_FAT = 0x81

FAT partition.

ESP_PARTITION_SUBTYPE_DATA_SPIFFS = 0x82

SPIFFS partition.

ESP_PARTITION_SUBTYPE_ANY = 0xff

Used to search for partitions with any subtype.

API Reference - Flash Encrypt

Functions

static 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.

Return

true if flash encryption is enabled.

esp_err_t esp_flash_encrypt_check_and_update(void)
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)

Encrypt-in-place a block of flash sectors.

Note

This function resets RTC_WDT between operations with sectors.

Return

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

Parameters
  • 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.

void esp_flash_write_protect_crypt_cnt()

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.

Note

To support disabling UART Download Mode on ESP32 V3 only, this function doesn’t write protect FLASH_CRYPT_CNT but instead sets it to the max value (effectively the same result but allows burning the UART_DL_DIS efuse later on, as this is otherwise also disabled if FLASH_CRYPT_CNT is write protected.)