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:
spi_flash_read()
used to read data from flash to RAMspi_flash_write()
used to write data from RAM to flashspi_flash_erase_sector()
used to erase individual sectors of flashspi_flash_erase_range()
used to erase range of addresses in flashspi_flash_get_chip_size()
returns flash chip size, in bytes, as configured in menuconfig
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
:
esp_partition_find()
used to search partition table for entries with specific type, returns an opaque iteratoresp_partition_get()
returns a structure describing the partition, for the given iteratoresp_partition_next()
advances iterator to the next partition foundesp_partition_iterator_release()
releases iterator returned byesp_partition_find
esp_partition_find_first()
is a convenience function which returns structure describing the first partition found byesp_partition_find
esp_partition_read()
,esp_partition_write()
,esp_partition_erase_range()
are equivalent tospi_flash_read()
,spi_flash_write()
,spi_flash_erase_range()
, but operate within partition boundaries
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
:
spi_flash_mmap()
maps a region of physical flash addresses into instruction space or data space of the CPUspi_flash_munmap()
unmaps previously mapped regionesp_partition_mmap()
maps part of a partition into the instruction space or data space of the CPU
Differences between spi_flash_mmap()
and esp_partition_mmap()
are as follows:
spi_flash_mmap()
must be given a 64KB aligned physical addressesp_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¶
Over The Air Update (OTA) API provides high-level API for updating app firmware stored in flash.
Non-Volatile Storage (NVS) API provides a structured API for storing small items of data in SPI flash.
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¶
Header File¶
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-alignedsize
: 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 buffersize
: 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 buffersize
: 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 boundarymemory
: 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 arraymemory
: 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¶
Header File¶
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 valuessubtype
: 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 valuessubtype
: 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 mappedout_ptr
: Output, pointer to the mapped memory regionout_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
-
esp_partition_type_t
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¶
Header File¶
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_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.)