Flash map
The <zephyr/storage/flash_map.h>
API allows accessing information about device
flash partitions via flash_area
structures.
Each flash_area
describes a flash partition. The API provides access
to a “flash map”, which contains predefined flash areas accessible via globally
unique ID numbers. The map is created from “fixed-partition” compatible entries
in DTS file. Users may also create flash_area
objects at runtime
for application-specific purposes.
This documentation uses “flash area” when referencing single “fixed-partition” entities.
The flash_area
contains a pointer to a device
,
which can be used to access the flash device an area is placed on directly
with the flash API.
Each flash area is characterized by a device it is placed on, offset
from the beginning of the device and size on the device.
An additional identifier parameter is used by the flash_area_open()
function to find flash area in flash map.
The flash_map.h API provides functions for operating on a flash_area
.
The main examples are flash_area_read()
and flash_area_write()
.
These functions are basically wrappers around the flash API with additional
offset and size checks, to limit flash operations to a predefined area.
Most <zephyr/storage/flash_map.h>
API functions require a flash_area
object pointer
characterizing the flash area they will be working on. There are two possible
methods to obtain such a pointer:
obtain it using flash_area_open;
defining a
flash_area
type object, which requires providing a validdevice
object pointer with offset and size of the area within the flash device.
flash_area_open()
uses numeric identifiers to search flash map for
flash_area
objects and returns, if found, a pointer to an object
representing area with given ID.
The ID number for a flash area can be obtained from a fixed-partition
DTS node label using FIXED_PARTITION_ID()
; these labels are obtained
from the devicetree as described below.
Relationship with Devicetree
The flash_map.h API uses data generated from the Devicetree API, in particular its Fixed flash partitions. Zephyr additionally has some partitioning conventions used for Device Firmware Upgrade via the MCUboot bootloader, as well as defining partitions usable by file systems or other nonvolatile storage.
Here is an example devicetree fragment which uses fixed flash partitions for both MCUboot and a storage partition. Some details were left out for clarity.
/ {
soc {
flashctrl: flash-controller@deadbeef {
flash0: flash@0 {
compatible = "soc-nv-flash";
reg = <0x0 0x100000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <0x1>;
#size-cells = <0x1>;
boot_partition: partition@0 {
reg = <0x0 0x10000>;
read-only;
};
storage_partition: partition@1e000 {
reg = <0x1e000 0x2000>;
};
slot0_partition: partition@20000 {
reg = <0x20000 0x60000>;
};
slot1_partition: partition@80000 {
reg = <0x80000 0x60000>;
};
scratch_partition: partition@e0000 {
reg = <0xe0000 0x20000>;
};
};
};
};
};
};
Partition offset shall be expressed in relation to the flash memory beginning address, to which the partition belongs to.
The boot_partition
, slot0_partition
, slot1_partition
, and
scratch_partition
node labels are defined for MCUboot, though not all MCUboot
configurations require all of them to be defined. See the MCUboot
documentation for more details.
The storage_partition
node is defined for use by a file system or other
nonvolatile storage API.
Numeric flash area ID is obtained by passing DTS node label to
FIXED_PARTITION_ID()
; for example to obtain ID number
for slot0_partition
, user would invoke FIXED_PARTITION_ID(slot0_partition)
.
All FIXED_PARTITION_
macros take DTS node labels as partition
identifiers.
Users do not have to obtain a flash_area
object pointer
using flash_map_open()
to get information on flash area size, offset
or device, if such area is defined in DTS file. Knowing the DTS node label
of an area, users may use FIXED_PARTITION_OFFSET()
,
FIXED_PARTITION_SIZE()
or FIXED_PARTITION_DEVICE()
respectively to obtain such information directly from DTS node definition.
For example to obtain offset of storage_partition
it is enough to
invoke FIXED_PARTITION_OFFSET(storage_partition)
.
Below example shows how to obtain a flash_area
object pointer
using flash_area_open()
and DTS node label:
const struct flash_area *my_area;
int err = flash_area_open(FIXED_PARTITION_ID(slot0_partition), &my_area);
if (err != 0) {
handle_the_error(err);
} else {
flash_area_read(my_area, ...);
}
API Reference
- group flash_area_api
Abstraction over flash partitions/areas and their drivers.
- Since
1.11
- Version
1.0.0
Defines
-
SOC_FLASH_0_ID
Provided for compatibility with MCUboot.
-
SPI_FLASH_0_ID
Provided for compatibility with MCUboot.
-
FIXED_PARTITION_EXISTS(label)
Returns non-0 value if fixed-partition of given DTS node label exists.
- Parameters:
label – DTS node label
- Returns:
non-0 if fixed-partition node exists and is enabled; 0 if node does not exist, is not enabled or is not fixed-partition.
-
FIXED_PARTITION_ID(label)
Get flash area ID from fixed-partition DTS node label.
- Parameters:
label – DTS node label of a partition
- Returns:
flash area ID
-
FIXED_PARTITION_OFFSET(label)
Get fixed-partition offset from DTS node label.
- Parameters:
label – DTS node label of a partition
- Returns:
fixed-partition offset, as defined for the partition in DTS.
-
FIXED_PARTITION_NODE_OFFSET(node)
Get fixed-partition offset from DTS node.
- Parameters:
node – DTS node of a partition
- Returns:
fixed-partition offset, as defined for the partition in DTS.
-
FIXED_PARTITION_SIZE(label)
Get fixed-partition size for DTS node label.
- Parameters:
label – DTS node label
- Returns:
fixed-partition offset, as defined for the partition in DTS.
-
FIXED_PARTITION_NODE_SIZE(node)
Get fixed-partition size for DTS node.
- Parameters:
node – DTS node of a partition
- Returns:
fixed-partition size, as defined for the partition in DTS.
-
FLASH_AREA_DEVICE(label)
Get device pointer for device the area/partition resides on.
- Parameters:
label – DTS node label of a partition
- Returns:
const struct device type pointer
-
FIXED_PARTITION_DEVICE(label)
Get device pointer for device the area/partition resides on.
- Parameters:
label – DTS node label of a partition
- Returns:
Pointer to a device.
-
FIXED_PARTITION_NODE_DEVICE(node)
Get device pointer for device the area/partition resides on.
- Parameters:
node – DTS node of a partition
- Returns:
Pointer to a device.
Typedefs
-
typedef void (*flash_area_cb_t)(const struct flash_area *fa, void *user_data)
Flash map iteration callback.
- Param fa:
flash area
- Param user_data:
User supplied data
Functions
-
int flash_area_open(uint8_t id, const struct flash_area **fa)
Retrieve partitions flash area from the flash_map.
Function Retrieves flash_area from flash_map for given partition.
- Parameters:
id – [in] ID of the flash partition.
fa – [out] Pointer which has to reference flash_area. If
ID
is unknown, it will be NULL on output.
- Returns:
0 on success, -EACCES if the flash_map is not available , -ENOENT if
ID
is unknown, -ENODEV if there is no driver attached to the area.
-
void flash_area_close(const struct flash_area *fa)
Close flash_area.
Reserved for future usage and external projects compatibility reason. Currently is NOP.
- Parameters:
fa – [in] Flash area to be closed.
-
int flash_area_read(const struct flash_area *fa, off_t off, void *dst, size_t len)
Read flash area data.
Read data from flash area. Area readout boundaries are asserted before read request. API has the same limitation regard read-block alignment and size as wrapped flash driver.
- Parameters:
fa – [in] Flash area
off – [in] Offset relative from beginning of flash area to read
dst – [out] Buffer to store read data
len – [in] Number of bytes to read
- Returns:
0 on success, negative errno code on fail.
-
int flash_area_write(const struct flash_area *fa, off_t off, const void *src, size_t len)
Write data to flash area.
Write data to flash area. Area write boundaries are asserted before write request. API has the same limitation regard write-block alignment and size as wrapped flash driver.
- Parameters:
fa – [in] Flash area
off – [in] Offset relative from beginning of flash area to write
src – [in] Buffer with data to be written
len – [in] Number of bytes to write
- Returns:
0 on success, negative errno code on fail.
-
int flash_area_erase(const struct flash_area *fa, off_t off, size_t len)
Erase flash area.
Erase given flash area range. Area boundaries are asserted before erase request. API has the same limitation regard erase-block alignment and size as wrapped flash driver.
- Parameters:
fa – [in] Flash area
off – [in] Offset relative from beginning of flash area.
len – [in] Number of bytes to be erase
- Returns:
0 on success, negative errno code on fail.
-
int flash_area_flatten(const struct flash_area *fa, off_t off, size_t len)
Erase flash area or fill with erase-value.
On program-erase devices this function behaves exactly like flash_area_erase. On RAM non-volatile device it will call erase, if driver provides such callback, or will fill given range with erase-value defined by driver. This function should be only used by code that has not been written to directly support devices that do not require erase and rely on device being erased prior to some operations. Note that emulated erase, on devices that do not require, is done via write, which affects endurance of device.
See also
See also
- Parameters:
fa – [in] Flash area
off – [in] Offset relative from beginning of flash area.
len – [in] Number of bytes to be erase
- Returns:
0 on success, negative errno code on fail.
-
uint32_t flash_area_align(const struct flash_area *fa)
Get write block size of the flash area.
Currently write block size might be treated as read block size, although most of drivers supports unaligned readout.
- Parameters:
fa – [in] Flash area
- Returns:
Alignment restriction for flash writes in [B].
-
int flash_area_get_sectors(int fa_id, uint32_t *count, struct flash_sector *sectors)
Retrieve info about sectors within the area.
- Parameters:
fa_id – [in] Given flash area ID
sectors – [out] buffer for sectors data
count – [inout] On input Capacity of
sectors
, on output number of sectors Retrieved.
- Returns:
0 on success, negative errno code on fail. Especially returns -ENOMEM if There are too many flash pages on the flash_area to fit in the array.
-
void flash_area_foreach(flash_area_cb_t user_cb, void *user_data)
Iterate over flash map.
- Parameters:
user_cb – User callback
user_data – User supplied data
-
int flash_area_has_driver(const struct flash_area *fa)
Check whether given flash area has supporting flash driver in the system.
- Parameters:
fa – [in] Flash area.
- Returns:
1 On success. -ENODEV if no driver match.
-
const struct device *flash_area_get_device(const struct flash_area *fa)
Get driver for given flash area.
- Parameters:
fa – [in] Flash area.
- Returns:
device driver.
-
uint8_t flash_area_erased_val(const struct flash_area *fa)
Get the value expected to be read when accessing any erased flash byte.
This API is compatible with the MCUBoot’s porting layer.
- Parameters:
fa – Flash area.
- Returns:
Byte value of erase memory.
-
struct flash_area
- #include <flash_map.h>
Flash partition.
This structure represents a fixed-size partition on a flash device. Each partition contains one or more flash sectors.
-
struct flash_sector
- #include <flash_map.h>
Structure for transfer flash sector boundaries.
This template is used for presentation of flash memory structure. It consumes much less RAM than flash_area