diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index 87810a896db..83c33a1d8d2 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -133,6 +133,28 @@ int flash_area_open(uint8_t id, const struct flash_area **fa); */ void flash_area_close(const struct flash_area *fa); +/** + * @brief Verify that a device assigned to flash area is ready for use. + * + * Indicates whether the provided flash area has a device known to be + * in a state where it can be used with Flash Map API. + * + * This can be used with struct flash_area pointers captured from + * FIXED_PARTITION(). + * At minimum this means that the device has been successfully initialized. + * + * @param[in] fa pointer to flash_area object to check. + * + * @retval true If the device is ready for use. + * @retval false If the device is not ready for use or if a NULL pointer is + * passed as flash area pointer or device pointer within flash area object + * is NULL. + */ +static ALWAYS_INLINE bool flash_area_device_is_ready(const struct flash_area *fa) +{ + return (fa != NULL && device_is_ready(fa->fa_dev)); +} + /** * @brief Read flash area data * @@ -376,6 +398,31 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_NODE_DEVICE(node) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(node)) +/** + * Get pointer to flash_area object by partition label + * + * @param label DTS node label of a partition + * + * @return Pointer to flash_area type object representing partition + */ +#define FIXED_PARTITION(label) FIXED_PARTITION_1(DT_NODELABEL(label)) +#define FIXED_PARTITION_1(node) FIXED_PARTITION_0(DT_DEP_ORD(node)) +#define FIXED_PARTITION_0(ord) (const struct flash_area *)&DT_CAT(global_fixed_partition_ORD_, part) + +/** @cond INTERNAL_HIDDEN */ +#define DECLARE_PARTITION(part) DECLARE_PARTITION_0(DT_DEP_ORD(part)) +#define DECLARE_PARTITION_0(part) \ + extern const struct flash_area DT_CAT(global_fixed_partition_ORD_, part); +#define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DECLARE_PARTITION) + +/* Generate declarations */ +DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE) + +#undef DECLARE_PARTITION +#undef DECLARE_PARTITION_0 +#undef FOR_EACH_PARTITION_TABLE +/** @endcond */ + #ifdef __cplusplus } #endif diff --git a/subsys/storage/flash_map/flash_map_default.c b/subsys/storage/flash_map/flash_map_default.c index ae1951b4a0e..55b4ba7490f 100644 --- a/subsys/storage/flash_map/flash_map_default.c +++ b/subsys/storage/flash_map/flash_map_default.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2017-2024 Nordic Semiconductor ASA * Copyright (c) 2015 Runtime Inc * Copyright (c) 2023 Sensorfy B.V. * @@ -43,3 +43,21 @@ const struct flash_area default_flash_map[] = { const int flash_map_entries = ARRAY_SIZE(default_flash_map); const struct flash_area *flash_map = default_flash_map; + +/* Generate objects representing each partition in system. In the end only + * objects referenced by code will be included into build. + */ +#define DEFINE_PARTITION(part) DEFINE_PARTITION_1(part, DT_DEP_ORD(part)) +#define DEFINE_PARTITION_1(part, ord) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_PARTITION(part)), \ + (DEFINE_PARTITION_0(part, ord)), ()) +#define DEFINE_PARTITION_0(part, ord) \ + const struct flash_area DT_CAT(global_fixed_partition_ORD_, ord) = { \ + .fa_id = DT_FIXED_PARTITION_ID(part), \ + .fa_off = DT_REG_ADDR(part), \ + .fa_dev = DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(part)), \ + .fa_size = DT_REG_SIZE(part), \ + }; + +#define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_PARTITION) +DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE)