diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index e10cb7c8c5fec..2c83b6fe44166 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -2,6 +2,7 @@ * SPDX-License-Identifier: Apache-2.0 * Copyright (c) 2020 Nordic Semiconductor * Copyright (c) 2020, Linaro Ltd. + * Copyright (c) 2025 Alexander Kozhinov * * Not a generated file. Feel free to modify. */ @@ -1322,6 +1323,18 @@ #define DT_STRING_TOKEN_BY_IDX(node_id, prop, idx) \ DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_TOKEN) +/** + * @brief Like DT_STRING_TOKEN_BY_IDX(), but with a fallback to default_value + * @param node_id node identifier + * @param prop lowercase-and-underscores property name + * @param idx the index to get + * @param default_value a fallback value to expand to + * @return the element in @p prop at index @p idx as a token + */ +#define DT_STRING_TOKEN_BY_IDX_OR(node_id, prop, idx, default_value) \ + COND_CODE_1(DT_PROP_HAS_IDX(node_id, prop, idx), \ + (DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)), (default_value)) + /** * @brief Like DT_STRING_TOKEN_BY_IDX(), but uppercased. * @@ -4418,6 +4431,17 @@ #define DT_INST_STRING_TOKEN_BY_IDX(inst, prop, idx) \ DT_STRING_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx) +/** + * @brief Like DT_INST_STRING_TOKEN_BY_IDX(), but with a fallback to default_value + * @param inst instance number + * @param prop lowercase-and-underscores property name + * @param idx the index to get + * @param default_value a fallback value to expand to + * @return the element in @p prop at index @p idx as a token + */ +#define DT_INST_STRING_TOKEN_BY_IDX_OR(inst, prop, idx, default_value) \ + DT_STRING_TOKEN_BY_IDX_OR(DT_DRV_INST(inst), prop, idx, default_value) + /** * @brief Like DT_INST_STRING_TOKEN_BY_IDX(), but uppercased. * @param inst instance number diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 54d95555fe694..70f17a8403732 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -3433,7 +3433,9 @@ ZTEST(devicetree_api, test_string_token) #define DT_DRV_COMPAT vnd_string_array_token ZTEST(devicetree_api, test_string_idx_token) { + /* The enum has 7 values in total - thus invalid idx starts with 16 */ enum token_string_idx { + token_idx_default, /* Tokens */ token_first_idx_zero, token_first_idx_one, @@ -3468,6 +3470,15 @@ ZTEST(devicetree_api, test_string_idx_token) zassert_equal(DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(test_str_array_token_1), val, 3), token_second_idx_three, ""); + /* Index is in range */ + zassert_equal(DT_STRING_TOKEN_BY_IDX_OR(DT_NODELABEL(test_str_array_token_1), val, 3, + token_idx_default), + token_second_idx_three, ""); + /* Index is out of range */ + zassert_equal(DT_STRING_TOKEN_BY_IDX_OR(DT_NODELABEL(test_str_array_token_1), val, 42, + token_idx_default), + token_idx_default, ""); + zassert_equal(DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(test_str_array_token_0), val, 0), TOKEN_FIRST_IDX_ZERO, ""); zassert_equal(DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(test_str_array_token_0), val, 1), @@ -3506,6 +3517,13 @@ ZTEST(devicetree_api, test_string_idx_token) zassert_equal(STRING_TOKEN_BY_IDX_VAR(DT_NODELABEL(test_str_array_token_1))[2], token_second_idx_two, ""); + /* Index is in range instance #0 corresponds to test_str_array_token_0 */ + zassert_equal(DT_INST_STRING_TOKEN_BY_IDX_OR(0, val, 2, token_idx_default), + token_first_idx_two, ""); + /* Index is out of range */ + zassert_equal(DT_INST_STRING_TOKEN_BY_IDX_OR(0, val, 21, token_idx_default), + token_idx_default, ""); + #define STRING_UPPER_TOKEN_BY_IDX_VAR(node_id) _CONCAT(var_upper_token, node_id) #define STRING_UPPER_TOKEN_BY_IDX_TEST_INST_EXPANSION(inst) \ enum token_string_idx STRING_UPPER_TOKEN_BY_IDX_VAR(DT_DRV_INST(inst))[] = { \