zephyr-rtos

Zephyr device tree: how to get the values of the named properties of a phandle behind a phandles, for all compatible nodes?


In my Zephyr DTS binding I have a node with a given compatibility, let's call it my_compatibilty, with an optional property of type phandles, let's call it things, allowed to have up to two elements. In my driver code I can build up an array of the leaves of this tree; for instance, I can make an array of the values of a string entry flibble within things, or NULL if not present, for all compatible nodes with:

#define GET_THINGS_LIST(i, name) {DT_PROP_BY_PHANDLE_IDX_OR(i, things, 0, name, NULL),  \
                                  DT_PROP_BY_PHANDLE_IDX_OR(i, things, 1, name, NULL)},

static const char *const leafValueFlibble[][2] = {
    DT_FOREACH_STATUS_OKAY_VARGS(my_compatibilty, GET_THINGS_LIST, flibble)
};

This is now easy to manage, a nice ordered list I can work with from C.

HOWEVER, I now need flibble to be a phandle-type property. How do I extend the macrobatics above so that I can still get at the leaves of the tree, i.e. for all compatible nodes, create arrays of the values of the named properties within flibble (or NULL/-1/some-known-value if not present to keep the order)?


Solution

  • Based on the question and comments, the solution would require a few macros:

    #define DEFAULT_VALUE { .bingInt = 0, .bingString = NULL, },
    
    // This node might have a flibble, if it does, follow it to get bingInt and bingString from the pointed to node
    #define HANDLE_FLIBBLE(node) \
      COND_CODE_1(DT_NODE_HAS_PROP(node, flibble), \
        ({  .bingInt = DT_PROP_BY_PHANDLE(node, flibble, bingInt), \
            .bingString = DT_PROP_BY_PHANDLE(node, flibble, bingString), },), \
        (DEFAULT_VALUE))
    
    // This node might have things, if it does, follow it to the flibble
    #define HANDLE_MY_COMPAT(node) { \
      COND_CODE_1(DT_PROP_HAS_IDX(node, thing, 0), \
        (HANDLE_FLIBBLE(DT_PHANDLE_BY_IDX(node, thing, 0))), \
        (DEFAULT_VALUE)) \
      COND_CODE_1(DT_PROP_HAS_IDX(node, thing, 1), \
        (HANDLE_FLIBBLE(DT_PHANDLE_BY_IDX(node, thing, 1))), \
        (DEFAULT_VALUE)) \
      },
    
    struct flibbles {
       int bingInt;
       const char *bingString;
    };
    
    // Define the array using HANDLE_MY_COMPAT
    const struct flibbles leafFlibbles[][2] = {
       DT_FOREACH_STATUS_OKAY(my_compatibilty, HANDLE_MY_COMPAT)
    };