From 11d782ce568d68e515574da2e4516aabb47dd047 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Fri, 28 Apr 2023 18:26:23 +0200 Subject: [PATCH] cmake: modules: add support for board extensions Board extensions are board fragments that may be present in any board root folder, under `${BOARD_ROOT}/extensions/${BOARD}`. The board extension directory may contain Kconfig fragments and/or devicetree overlays. Board extensions are automatically loaded and applied on top of board files, before anything else. There is no guarantee on which order extensions are applied, in case multiple exist. Board extensions may be useful in the context of Zephyr modules, such as `example-application`. In some situations, certain hardware description or choices can not be added in the upstream Zephyr context, but they do in a downstream project, where custom bindings or driver classes can also be created. This feature may also be useful in development phases, when the board skeleton lives upstream, but other board features are not yet present. Signed-off-by: Gerard Marull-Paretas --- cmake/modules/boards.cmake | 34 +++++++++++++++++++++----- cmake/modules/dts.cmake | 3 +++ cmake/modules/kconfig.cmake | 2 ++ doc/hardware/porting/board_porting.rst | 31 +++++++++++++++++++++++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/cmake/modules/boards.cmake b/cmake/modules/boards.cmake index c9c86030693..77f61c32f7b 100644 --- a/cmake/modules/boards.cmake +++ b/cmake/modules/boards.cmake @@ -5,7 +5,9 @@ # Validate board and setup boards target. # # This CMake module will validate the BOARD argument as well as splitting the -# BOARD argument into and . +# BOARD argument into and . When BOARD_EXTENSIONS option +# is enabled (default) this module will also take care of finding board +# extension directories. # # If a board implementation is not found for the specified board an error will # be raised and list of valid boards will be printed. @@ -19,11 +21,13 @@ # Outcome: # The following variables will be defined when this CMake module completes: # -# - BOARD: Board, without revision field. -# - BOARD_REVISION: Board revision -# - BOARD_DIR: Board directory with the implementation for selected board -# - ARCH_DIR: Arch dir for extracted from selected board -# - BOARD_ROOT: BOARD_ROOT with ZEPHYR_BASE appended +# - BOARD: Board, without revision field. +# - BOARD_REVISION: Board revision +# - BOARD_DIR: Board directory with the implementation for selected board +# - ARCH_DIR: Arch dir for extracted from selected board +# - BOARD_ROOT: BOARD_ROOT with ZEPHYR_BASE appended +# - BOARD_EXTENSION_DIRS: List of board extension directories (If +# BOARD_EXTENSIONS is not explicitly disabled) # # The following targets will be defined when this CMake module completes: # - board: when invoked, a list of valid boards will be printed @@ -164,3 +168,21 @@ if(NOT BOARD_DIR) endif() add_custom_target(boards ${list_boards_commands} USES_TERMINAL) + +# Board extensions are enabled by default +set(BOARD_EXTENSIONS ON CACHE BOOL "Support board extensions") +zephyr_get(BOARD_EXTENSIONS) + +# Process board extensions +if(BOARD_EXTENSIONS) + get_filename_component(board_dir_name ${BOARD_DIR} NAME) + + foreach(root ${BOARD_ROOT}) + set(board_extension_dir ${root}/boards/extensions/${board_dir_name}) + if(NOT EXISTS ${board_extension_dir}) + continue() + endif() + + list(APPEND BOARD_EXTENSION_DIRS ${board_extension_dir}) + endforeach() +endif() diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index e21d9ead887..8236195ff85 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -150,8 +150,11 @@ endif() # with them. # +zephyr_file(CONF_FILES ${BOARD_EXTENSION_DIRS} DTS board_extension_dts_files) + set(dts_files ${DTS_SOURCE} + ${board_extension_dts_files} ${shield_dts_files} ) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 9e4a6320b4c..7c4a059b570 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -84,6 +84,7 @@ if(EXTRA_CONF_FILE) string(REPLACE " " ";" EXTRA_CONF_FILE_AS_LIST "${EXTRA_CONF_FILE_EXPANDED}") endif() +zephyr_file(CONF_FILES ${BOARD_EXTENSION_DIRS} KCONF board_extension_conf_files) # DTS_ROOT_BINDINGS is a semicolon separated list, this causes # problems when invoking kconfig_target since semicolon is a special @@ -252,6 +253,7 @@ set( merge_config_files ${BOARD_DEFCONFIG} ${BOARD_REVISION_CONFIG} + ${board_extension_conf_files} ${CONF_FILE_AS_LIST} ${shield_conf_files} ${EXTRA_CONF_FILE_AS_LIST} diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index 00709215920..8482eacc726 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -242,6 +242,37 @@ followed by trial and error. If you want to understand details, you will need to read the rest of the devicetree documentation and the devicetree specification. +Board extensions +**************** + +Board extensions are board fragments that can be present in a board root +folder, under ``${BOARD_ROOT}/boards/extensions``. The extension folder must +follow the naming structure of the original board to extend. The board extension +directory may contain Kconfig fragments and/or devicetree overlays. Board +extensions are, by default, automatically loaded and applied on top of board +files, before anything else. There is no guarantee on which order extensions are +applied, in case multiple exist. This feature shall be disabled by passing +``-DBOARD_EXTENSIONS=OFF`` when building. + +Board extensions are designed for downstream users, for example, +``example-application`` or vendor SDKs. In some situations, certain hardware +description or `choices `_ can not be added in the +upstream Zephyr repository, but they can be in a downstream project, where +custom bindings or driver classes can also be created. This feature may also be +useful in development phases, when the board skeleton lives upstream, but other +features are developed in a downstream module. + +Note that board extensions need to follow the +:ref:`same guidelines ` as regular boards. For +example, it is wrong to enable extra peripherals or subsystems in a board +extension. + +.. warning:: + + Board extensions are not allowed in any module referenced in Zephyr's + ``west.yml`` manifest file. Any board changes are required to be submitted to + the main Zephyr repository. + .. _dt_k6x_example: Example: FRDM-K64F and Hexiwear K64