diff --git a/include/zephyr/devicetree/fixed-partitions.h b/include/zephyr/devicetree/fixed-partitions.h index 14bb96bfc59..d9860f69d5a 100644 --- a/include/zephyr/devicetree/fixed-partitions.h +++ b/include/zephyr/devicetree/fixed-partitions.h @@ -131,7 +131,9 @@ extern "C" { * node containing it. */ #define DT_FIXED_PARTITION_ADDR(node_id) \ - (DT_REG_ADDR(DT_MEM_FROM_FIXED_PARTITION(node_id)) + DT_REG_ADDR(node_id)) + (DT_REG_ADDR(node_id) + (DT_REG_ADDR(COND_CODE_1( \ + DT_NODE_EXISTS(DT_MEM_FROM_FIXED_PARTITION(node_id)), \ + (DT_MEM_FROM_FIXED_PARTITION(node_id)), (DT_GPARENT(node_id)))))) /** * @brief Test if fixed-subpartitions compatible node exists @@ -160,7 +162,7 @@ extern "C" { */ #define DT_MTD_FROM_FIXED_SUBPARTITION(node_id) \ COND_CODE_1(DT_NODE_EXISTS(DT_MEM_FROM_FIXED_SUBPARTITION(node_id)), \ - (DT_PARENT(DT_MEM_FROM_FIXED_SUBPARTITION(node_id))), (DT_GPARENT(node_id))) + (DT_PARENT(DT_MEM_FROM_FIXED_SUBPARTITION(node_id))), (DT_GPARENT(DT_PARENT(node_id)))) /** * @brief Get the absolute address of a fixed subpartition @@ -207,7 +209,9 @@ extern "C" { * node containing it. */ #define DT_FIXED_SUBPARTITION_ADDR(node_id) \ - (DT_REG_ADDR(DT_MEM_FROM_FIXED_SUBPARTITION(node_id)) + DT_REG_ADDR(node_id)) + (DT_REG_ADDR(node_id) + (DT_REG_ADDR(COND_CODE_1( \ + DT_NODE_EXISTS(DT_MEM_FROM_FIXED_SUBPARTITION(node_id)), \ + (DT_MEM_FROM_FIXED_SUBPARTITION(node_id)), (DT_GPARENT(DT_PARENT(node_id))))))) /** * @} diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index f62f1c21718..91175068541 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -353,14 +353,17 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #else /** - * Returns non-0 value if fixed-partition of given DTS node label exists. + * Returns non-0 value if fixed-partition as well as fixed-subpartition of given + * DTS node label exists. * * @param label DTS node label * * @return non-0 if fixed-partition node exists and is enabled; * 0 if node does not exist, is not enabled or is not fixed-partition. */ -#define FIXED_PARTITION_EXISTS(label) DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label)) +#define FIXED_PARTITION_EXISTS(label) \ + UTIL_OR(DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label)), \ + DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label))) /** * Get flash area ID from fixed-partition DTS node label @@ -372,7 +375,7 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_ID(label) DT_FIXED_PARTITION_ID(DT_NODELABEL(label)) /** - * Get fixed-partition offset from DTS node label + * Get fixed-partition as well as fixed-subpartition offset from DTS node label * * @param label DTS node label of a partition * @@ -380,6 +383,30 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); */ #define FIXED_PARTITION_OFFSET(label) DT_REG_ADDR(DT_NODELABEL(label)) +/** + * Get fixed-partition as well as fixed-subpartition address from DTS node label + * + * @param label DTS node label of a partition or subpartition + * + * @return fixed-partition address, as defined for the partition in DTS. + */ +#define FIXED_PARTITION_ADDRESS(label) \ + (COND_CODE_1(DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \ + (DT_FIXED_SUBPARTITION_ADDR(DT_NODELABEL(label))), \ + (DT_FIXED_PARTITION_ADDR(DT_NODELABEL(label))))) + +/** + * Get fixed-partition as well as fixed-subpartition address from DTS node + * + * @param node DTS node of a partition + * + * @return fixed-partition address, as defined for the partition in DTS. + */ +#define FIXED_PARTITION_NODE_ADDRESS(node) \ + (COND_CODE_1(DT_FIXED_SUBPARTITION_EXISTS(node), \ + (DT_FIXED_SUBPARTITION_ADDR(node)), \ + (DT_FIXED_PARTITION_ADDR(node)))) + /** * Get fixed-partition offset from DTS node * @@ -425,8 +452,10 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); * @return Pointer to a device. */ #define FIXED_PARTITION_DEVICE(label) \ - DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) - + DEVICE_DT_GET(COND_CODE_1( \ + DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \ + (DT_MTD_FROM_FIXED_SUBPARTITION(DT_NODELABEL(label))), \ + (DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))))) /** * Get device pointer for device the area/partition resides on * @@ -435,7 +464,10 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); * @return Pointer to a device. */ #define FIXED_PARTITION_NODE_DEVICE(node) \ - DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(node)) + DEVICE_DT_GET(COND_CODE_1( \ + DT_FIXED_SUBPARTITION_EXISTS(node), \ + (DT_MTD_FROM_FIXED_SUBPARTITION(node)), \ + (DT_MTD_FROM_FIXED_PARTITION(node)))) /** * Get pointer to flash_area object by partition label @@ -471,6 +503,22 @@ DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE) #undef DECLARE_PARTITION #undef DECLARE_PARTITION_0 #undef FOR_EACH_PARTITION_TABLE + +#define FIXED_SUBPARTITION_1(node) FIXED_SUBPARTITION_0(DT_DEP_ORD(node)) +#define FIXED_SUBPARTITION_0(ord) \ + ((const struct flash_area *)&DT_CAT(global_fixed_subpartition_ORD_, ord)) + +#define DECLARE_SUBPARTITION(node) DECLARE_SUBPARTITION_0(DT_DEP_ORD(node)) +#define DECLARE_SUBPARTITION_0(ord) \ + extern const struct flash_area DT_CAT(global_fixed_subpartition_ORD_, ord); +#define FOR_EACH_SUBPARTITION_TABLE(table) DT_FOREACH_CHILD(table, DECLARE_SUBPARTITION) + +/* Generate declarations */ +DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOR_EACH_SUBPARTITION_TABLE) + +#undef DECLARE_SUBPARTITION +#undef DECLARE_SUBPARTITION_0 +#undef FOR_EACH_SUBPARTITION_TABLE /** @endcond */ #endif /* USE_PARTITION_MANAGER */ diff --git a/subsys/storage/flash_map/flash_map_default.c b/subsys/storage/flash_map/flash_map_default.c index c0514d28a12..6b1edfbbaef 100644 --- a/subsys/storage/flash_map/flash_map_default.c +++ b/subsys/storage/flash_map/flash_map_default.c @@ -40,6 +40,7 @@ */ const struct flash_area default_flash_map[] = { DT_FOREACH_STATUS_OKAY(fixed_partitions, FOREACH_PARTITION) + DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOREACH_PARTITION) }; const int flash_map_entries = ARRAY_SIZE(default_flash_map); @@ -63,11 +64,11 @@ const struct flash_area *flash_map = default_flash_map; #define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_PARTITION) DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE) -#define DEFINE_SUB_PARTITION(part) DEFINE_SUB_PARTITION_1(part, DT_DEP_ORD(part)) -#define DEFINE_SUB_PARTITION_1(part, ord) \ +#define DEFINE_SUBPARTITION(part) DEFINE_SUBPARTITION_1(part, DT_DEP_ORD(part)) +#define DEFINE_SUBPARTITION_1(part, ord) \ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_SUBPARTITION(part)), \ - (DEFINE_SUB_PARTITION_0(part, ord)), ()) -#define DEFINE_SUB_PARTITION_0(part, ord) \ + (DEFINE_SUBPARTITION_0(part, ord)), ()) +#define DEFINE_SUBPARTITION_0(part, ord) \ const struct flash_area DT_CAT(global_fixed_subpartition_ORD_, ord) = { \ .fa_id = DT_FIXED_PARTITION_ID(part), \ .fa_off = DT_REG_ADDR(part), \ @@ -75,5 +76,5 @@ DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE) .fa_size = DT_REG_SIZE(part), \ }; -#define FOR_EACH_SUB_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_SUB_PARTITION) -DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOR_EACH_SUB_PARTITION_TABLE) +#define FOR_EACH_SUBPARTITION_TABLE(table) DT_FOREACH_CHILD(table, DEFINE_SUBPARTITION) +DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOR_EACH_SUBPARTITION_TABLE) diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 98189ebe582..6c154d6dd5e 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -3271,13 +3271,7 @@ ZTEST(devicetree_api, test_fixed_partitions) /* Test DT_FIXED_PARTITION_ADDR. */ zassert_equal(DT_FIXED_PARTITION_ADDR(TEST_PARTITION_0), 0x20000000); zassert_equal(DT_FIXED_PARTITION_ADDR(TEST_PARTITION_1), 0x200000c0); - - /* DT_FIXED_PARTITION_ADDR(TEST_PARTITION_2) expands to an invalid expression. - * Test this by way of string comparison. - */ - zassert_true(!strcmp(TO_STRING(DT_FIXED_PARTITION_ADDR(TEST_PARTITION_2)), - "(__REG_IDX_0_VAL_ADDRESSU + 458624U)")); - zassert_equal(DT_REG_ADDR(TEST_PARTITION_2), 458624); + zassert_equal(DT_FIXED_PARTITION_ADDR(TEST_PARTITION_2), 0x33291080); /* Test that all DT_FIXED_PARTITION_ID are defined and unique. */ #define FIXED_PARTITION_ID_COMMA(node_id) DT_FIXED_PARTITION_ID(node_id), @@ -3312,6 +3306,9 @@ ZTEST(devicetree_api, test_fixed_subpartitions) zassert_true(DT_NODE_EXISTS(DT_MTD_FROM_FIXED_PARTITION(TEST_SUBPARTITION_COMBINED))); zassert_true(DT_NODE_EXISTS(DT_MTD_FROM_FIXED_SUBPARTITION(TEST_SUBPARTITION_0))); zassert_true(DT_NODE_EXISTS(DT_MTD_FROM_FIXED_SUBPARTITION(TEST_SUBPARTITION_1))); + zassert_true(DT_SAME_NODE( + DT_MTD_FROM_FIXED_PARTITION(TEST_SUBPARTITION_COMBINED), + DT_MTD_FROM_FIXED_SUBPARTITION(TEST_SUBPARTITION_1))); /* Test DT_FIXED_SUBPARTITION_ADDR. */ zassert_equal(DT_FIXED_PARTITION_ADDR(TEST_SUBPARTITION_COMBINED), 0x20000100);