LCOV - code coverage report
Current view: top level - zephyr/sys - iterable_sections.h Coverage Total Hit
Test: new.info Lines: 95.7 % 23 22
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (C) 2020, Intel Corporation
       3              :  * Copyright (C) 2023, Nordic Semiconductor ASA
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef INCLUDE_ZEPHYR_SYS_ITERABLE_SECTIONS_H_
       8              : #define INCLUDE_ZEPHYR_SYS_ITERABLE_SECTIONS_H_
       9              : 
      10              : #include <zephyr/sys/__assert.h>
      11              : #include <zephyr/toolchain.h>
      12              : 
      13              : #ifdef __cplusplus
      14              : extern "C" {
      15              : #endif
      16              : 
      17              : /**
      18              :  * @brief Iterable Sections APIs
      19              :  * @defgroup iterable_section_apis Iterable Sections APIs
      20              :  * @ingroup os_services
      21              :  * @{
      22              :  */
      23              : 
      24              : /**
      25              :  * @brief Defines a new element for an iterable section for a generic type.
      26              :  *
      27              :  * @details
      28              :  * Convenience helper combining __in_section() and Z_DECL_ALIGN().
      29              :  * The section name will be '.[SECNAME].static.[SECTION_POSTFIX]'
      30              :  *
      31              :  * In the linker script, create output sections for these using
      32              :  * ITERABLE_SECTION_ROM() or ITERABLE_SECTION_RAM().
      33              :  *
      34              :  * @note In order to store the element in ROM, a const specifier has to
      35              :  * be added to the declaration: const TYPE_SECTION_ITERABLE(...);
      36              :  *
      37              :  * @param[in]  type data type of variable
      38              :  * @param[in]  varname name of variable to place in section
      39              :  * @param[in]  secname type name of iterable section.
      40              :  * @param[in]  section_postfix postfix to use in section name
      41              :  */
      42            1 : #define TYPE_SECTION_ITERABLE(type, varname, secname, section_postfix) \
      43              :         Z_DECL_ALIGN(type) varname \
      44              :         __in_section(_##secname, static, _CONCAT(section_postfix, _)) __used __noasan
      45              : 
      46              : /**
      47              :  * @brief iterable section start symbol for a generic type
      48              :  *
      49              :  * will return '_[OUT_TYPE]_list_start'.
      50              :  *
      51              :  * @param[in]  secname type name of iterable section.  For 'struct foobar' this
      52              :  * would be TYPE_SECTION_START(foobar)
      53              :  *
      54              :  */
      55            1 : #define TYPE_SECTION_START(secname) _CONCAT(_##secname, _list_start)
      56              : 
      57              : /**
      58              :  * @brief iterable section end symbol for a generic type
      59              :  *
      60              :  * will return '_<SECNAME>_list_end'.
      61              :  *
      62              :  * @param[in]  secname type name of iterable section.  For 'struct foobar' this
      63              :  * would be TYPE_SECTION_START(foobar)
      64              :  */
      65            1 : #define TYPE_SECTION_END(secname) _CONCAT(_##secname, _list_end)
      66              : 
      67              : /**
      68              :  * @brief iterable section extern for start symbol for a generic type
      69              :  *
      70              :  * Helper macro to give extern for start of iterable section.  The macro
      71              :  * typically will be called TYPE_SECTION_START_EXTERN(struct foobar, foobar).
      72              :  * This allows the macro to hand different types as well as cases where the
      73              :  * type and section name may differ.
      74              :  *
      75              :  * @param[in]  type data type of section
      76              :  * @param[in]  secname name of output section
      77              :  */
      78            1 : #define TYPE_SECTION_START_EXTERN(type, secname) \
      79              :         extern type TYPE_SECTION_START(secname)[]
      80              : 
      81              : /**
      82              :  * @brief iterable section extern for end symbol for a generic type
      83              :  *
      84              :  * Helper macro to give extern for end of iterable section.  The macro
      85              :  * typically will be called TYPE_SECTION_END_EXTERN(struct foobar, foobar).
      86              :  * This allows the macro to hand different types as well as cases where the
      87              :  * type and section name may differ.
      88              :  *
      89              :  * @param[in]  type data type of section
      90              :  * @param[in]  secname name of output section
      91              :  */
      92            1 : #define TYPE_SECTION_END_EXTERN(type, secname) \
      93              :         extern type TYPE_SECTION_END(secname)[]
      94              : 
      95              : /**
      96              :  * @brief Iterate over a specified iterable section for a generic type
      97              :  *
      98              :  * @details
      99              :  * Iterator for structure instances gathered by TYPE_SECTION_ITERABLE().
     100              :  * The linker must provide a _<SECNAME>_list_start symbol and a
     101              :  * _<SECNAME>_list_end symbol to mark the start and the end of the
     102              :  * list of struct objects to iterate over. This is normally done using
     103              :  * ITERABLE_SECTION_ROM() or ITERABLE_SECTION_RAM() in the linker script.
     104              :  */
     105            1 : #define TYPE_SECTION_FOREACH(type, secname, iterator)           \
     106              :         TYPE_SECTION_START_EXTERN(type, secname);               \
     107              :         TYPE_SECTION_END_EXTERN(type, secname);         \
     108              :         for (type * iterator = TYPE_SECTION_START(secname); ({  \
     109              :                 __ASSERT(iterator <= TYPE_SECTION_END(secname),\
     110              :                               "unexpected list end location");        \
     111              :                      iterator < TYPE_SECTION_END(secname);   \
     112              :              });                                                \
     113              :              iterator++)
     114              : 
     115              : /**
     116              :  * @brief Get element from section for a generic type.
     117              :  *
     118              :  * @note There is no protection against reading beyond the section.
     119              :  *
     120              :  * @param[in]  type type of element
     121              :  * @param[in]  secname name of output section
     122              :  * @param[in]  i Index.
     123              :  * @param[out] dst Pointer to location where pointer to element is written.
     124              :  */
     125            1 : #define TYPE_SECTION_GET(type, secname, i, dst) do { \
     126              :         TYPE_SECTION_START_EXTERN(type, secname); \
     127              :         *(dst) = &TYPE_SECTION_START(secname)[i]; \
     128              : } while (0)
     129              : 
     130              : /**
     131              :  * @brief Count elements in a section for a generic type.
     132              :  *
     133              :  * @param[in]  type type of element
     134              :  * @param[in]  secname name of output section
     135              :  * @param[out] dst Pointer to location where result is written.
     136              :  */
     137            1 : #define TYPE_SECTION_COUNT(type, secname, dst) do { \
     138              :         TYPE_SECTION_START_EXTERN(type, secname); \
     139              :         TYPE_SECTION_END_EXTERN(type, secname); \
     140              :         *(dst) = ((uintptr_t)TYPE_SECTION_END(secname) - \
     141              :                   (uintptr_t)TYPE_SECTION_START(secname)) / sizeof(type); \
     142              : } while (0)
     143              : 
     144              : /**
     145              :  * @brief iterable section start symbol for a struct type
     146              :  *
     147              :  * @param[in]  struct_type data type of section
     148              :  */
     149            1 : #define STRUCT_SECTION_START(struct_type) \
     150              :         TYPE_SECTION_START(struct_type)
     151              : 
     152              : /**
     153              :  * @brief iterable section extern for start symbol for a struct
     154              :  *
     155              :  * Helper macro to give extern for start of iterable section.
     156              :  *
     157              :  * @param[in]  struct_type data type of section
     158              :  */
     159            1 : #define STRUCT_SECTION_START_EXTERN(struct_type) \
     160              :         TYPE_SECTION_START_EXTERN(struct struct_type, struct_type)
     161              : 
     162              : /**
     163              :  * @brief iterable section end symbol for a struct type
     164              :  *
     165              :  * @param[in]  struct_type data type of section
     166              :  */
     167            1 : #define STRUCT_SECTION_END(struct_type) \
     168              :         TYPE_SECTION_END(struct_type)
     169              : 
     170              : /**
     171              :  * @brief iterable section extern for end symbol for a struct
     172              :  *
     173              :  * Helper macro to give extern for end of iterable section.
     174              :  *
     175              :  * @param[in]  struct_type data type of section
     176              :  */
     177            1 : #define STRUCT_SECTION_END_EXTERN(struct_type) \
     178              :         TYPE_SECTION_END_EXTERN(struct struct_type, struct_type)
     179              : 
     180              : /**
     181              :  * @brief Defines a new element of alternate data type for an iterable section.
     182              :  *
     183              :  * @details
     184              :  * Special variant of STRUCT_SECTION_ITERABLE(), for placing alternate
     185              :  * data types within the iterable section of a specific data type. The
     186              :  * data type sizes and semantics must be equivalent!
     187              :  */
     188            1 : #define STRUCT_SECTION_ITERABLE_ALTERNATE(secname, struct_type, varname) \
     189              :         TYPE_SECTION_ITERABLE(struct struct_type, varname, secname, varname)
     190              : 
     191              : /**
     192              :  * @brief Defines an array of elements of alternate data type for an iterable
     193              :  * section.
     194              :  *
     195              :  * @see STRUCT_SECTION_ITERABLE_ALTERNATE
     196              :  */
     197              : #define STRUCT_SECTION_ITERABLE_ARRAY_ALTERNATE(secname, struct_type, varname, \
     198            1 :                                                 size)                          \
     199              :         TYPE_SECTION_ITERABLE(struct struct_type, varname[size], secname,      \
     200              :                               varname)
     201              : 
     202              : /**
     203              :  * @brief Defines a new element for an iterable section.
     204              :  *
     205              :  * @details
     206              :  * Convenience helper combining __in_section() and Z_DECL_ALIGN().
     207              :  * The section name is the struct type prepended with an underscore.
     208              :  * The subsection is "static" and the subsubsection is the variable name.
     209              :  *
     210              :  * In the linker script, create output sections for these using
     211              :  * ITERABLE_SECTION_ROM() or ITERABLE_SECTION_RAM().
     212              :  *
     213              :  * @note In order to store the element in ROM, a const specifier has to
     214              :  * be added to the declaration: const STRUCT_SECTION_ITERABLE(...);
     215              :  */
     216            1 : #define STRUCT_SECTION_ITERABLE(struct_type, varname) \
     217              :         STRUCT_SECTION_ITERABLE_ALTERNATE(struct_type, struct_type, varname)
     218              : 
     219              : /**
     220              :  * @brief Defines an array of elements for an iterable section.
     221              :  *
     222              :  * @see STRUCT_SECTION_ITERABLE
     223              :  */
     224            1 : #define STRUCT_SECTION_ITERABLE_ARRAY(struct_type, varname, size)              \
     225              :         STRUCT_SECTION_ITERABLE_ARRAY_ALTERNATE(struct_type, struct_type,      \
     226              :                                                 varname, size)
     227              : 
     228              : /**
     229              :  * @brief Defines a new element for an iterable section with a custom name.
     230              :  *
     231              :  * The name can be used to customize how iterable section entries are sorted.
     232              :  * @see STRUCT_SECTION_ITERABLE()
     233              :  */
     234            1 : #define STRUCT_SECTION_ITERABLE_NAMED(struct_type, name, varname) \
     235              :         TYPE_SECTION_ITERABLE(struct struct_type, varname, struct_type, name)
     236              : 
     237              : /**
     238              :  * @brief Defines a new element for an iterable section with a custom name,
     239              :  * placed in a custom section.
     240              :  *
     241              :  * The name can be used to customize how iterable section entries are sorted.
     242              :  * @see STRUCT_SECTION_ITERABLE_NAMED()
     243              :  */
     244            1 : #define STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(struct_type, secname, name, varname) \
     245              :         TYPE_SECTION_ITERABLE(struct struct_type, varname, secname, name)
     246              : 
     247              : /**
     248              :  * @brief Iterate over a specified iterable section (alternate).
     249              :  *
     250              :  * @details
     251              :  * Iterator for structure instances gathered by STRUCT_SECTION_ITERABLE().
     252              :  * The linker must provide a _<SECNAME>_list_start symbol and a
     253              :  * _<SECNAME>_list_end symbol to mark the start and the end of the
     254              :  * list of struct objects to iterate over. This is normally done using
     255              :  * ITERABLE_SECTION_ROM() or ITERABLE_SECTION_RAM() in the linker script.
     256              :  */
     257            1 : #define STRUCT_SECTION_FOREACH_ALTERNATE(secname, struct_type, iterator) \
     258              :         TYPE_SECTION_FOREACH(struct struct_type, secname, iterator)
     259              : 
     260              : /**
     261              :  * @brief Iterate over a specified iterable section.
     262              :  *
     263              :  * @details
     264              :  * Iterator for structure instances gathered by STRUCT_SECTION_ITERABLE().
     265              :  * The linker must provide a _<struct_type>_list_start symbol and a
     266              :  * _<struct_type>_list_end symbol to mark the start and the end of the
     267              :  * list of struct objects to iterate over. This is normally done using
     268              :  * ITERABLE_SECTION_ROM() or ITERABLE_SECTION_RAM() in the linker script.
     269              :  */
     270            1 : #define STRUCT_SECTION_FOREACH(struct_type, iterator) \
     271              :         STRUCT_SECTION_FOREACH_ALTERNATE(struct_type, struct_type, iterator)
     272              : 
     273              : /**
     274              :  * @brief Get element from section.
     275              :  *
     276              :  * @note There is no protection against reading beyond the section.
     277              :  *
     278              :  * @param[in]  struct_type Struct type.
     279              :  * @param[in]  i Index.
     280              :  * @param[out] dst Pointer to location where pointer to element is written.
     281              :  */
     282            1 : #define STRUCT_SECTION_GET(struct_type, i, dst) \
     283              :         TYPE_SECTION_GET(struct struct_type, struct_type, i, dst)
     284              : 
     285              : /**
     286              :  * @brief Count elements in a section.
     287              :  *
     288              :  * @param[in]  struct_type Struct type
     289              :  * @param[out] dst Pointer to location where result is written.
     290              :  */
     291            1 : #define STRUCT_SECTION_COUNT(struct_type, dst) \
     292              :         TYPE_SECTION_COUNT(struct struct_type, struct_type, dst);
     293              : 
     294              : /**
     295              :  * @}
     296              :  */ /* end of struct_section_apis */
     297              : 
     298              : #ifdef __cplusplus
     299              : }
     300              : #endif
     301              : 
     302              : #endif /* INCLUDE_ZEPHYR_SYS_ITERABLE_SECTIONS_H_ */
        

Generated by: LCOV version 2.0-1