diff --git a/cmake/modules/shields.cmake b/cmake/modules/shields.cmake index 145f559b2922d2f..91d23ee26f34985 100644 --- a/cmake/modules/shields.cmake +++ b/cmake/modules/shields.cmake @@ -35,6 +35,15 @@ include(extensions) # Check that SHIELD has not changed. zephyr_check_cache(SHIELD WATCH) +set(GEN_SHIELD_DERIVED_OVERLAY_SCRIPT ${ZEPHYR_BASE}/scripts/build/gen_shield_derived_overlay.py) +set(GENERATED_SHIELDS_DIR ${PROJECT_BINARY_DIR}/include/generated/shields) + +# Add the directory derived overlay files to the SHIELD_DIRS output variable. +list(APPEND + SHIELD_DIRS + ${GENERATED_SHIELDS_DIR} +) + if(SHIELD) message(STATUS "Shield(s): ${SHIELD}") endif() @@ -44,7 +53,7 @@ if(DEFINED SHIELD) endif() # SHIELD-NOTFOUND is a real CMake list, from which valid shields can be popped. # After processing all shields, only invalid shields will be left in this list. -set(SHIELD-NOTFOUND ${SHIELD_AS_LIST}) +string(REGEX REPLACE "([@:][^;]*)" "" SHIELD-NOTFOUND "${SHIELD}") foreach(root ${BOARD_ROOT}) set(shield_dir ${root}/boards/shields) @@ -74,43 +83,73 @@ endforeach() # Process shields in-order if(DEFINED SHIELD) - foreach(s ${SHIELD_AS_LIST}) + foreach(shld ${SHIELD_AS_LIST}) + string(REGEX MATCH [[^([^@:]*)([@:].*)?$]] matched "${shld}") + set(s ${CMAKE_MATCH_1}) # name part + set(shld_opts ${CMAKE_MATCH_2}) # options part + if(NOT ${s} IN_LIST SHIELD_LIST) continue() endif() list(REMOVE_ITEM SHIELD-NOTFOUND ${s}) - # Add .overlay to the shield_dts_files output variable. - list(APPEND - shield_dts_files - ${SHIELD_DIR_${s}}/${s}.overlay - ) - # Add the shield's directory to the SHIELD_DIRS output variable. list(APPEND SHIELD_DIRS ${SHIELD_DIR_${s}} ) - # Search for shield/shield.conf file - if(EXISTS ${SHIELD_DIR_${s}}/${s}.conf) - list(APPEND - shield_conf_files - ${SHIELD_DIR_${s}}/${s}.conf - ) - endif() - # Add board-specific .conf and .overlay files to their # respective output variables. zephyr_file(CONF_FILES ${SHIELD_DIR_${s}}/boards - DTS shield_dts_files - KCONF shield_conf_files + DTS board_overlay_file + KCONF board_conf_file ) + zephyr_file(CONF_FILES ${SHIELD_DIR_${s}}/boards/${s} - DTS shield_dts_files - KCONF shield_conf_files + DTS board_shield_overlay_file + KCONF board_shield_conf_file ) + + get_filename_component(board_overlay_stem "${board_overlay_file}" NAME_WE) + get_filename_component(shield_overlay_stem "${board_shield_overlay_file}" NAME_WE) + + set(shld_conf_srcs + "${SHIELD_DIR_${s}}/${s}.conf" + "${board_conf_file}" + "${board_shield_conf_file}") + + set(shld_overlay_srcs + "${SHIELD_DIR_${s}}/${s}.overlay" + "${board_overlay_file}" + "${board_shield_overlay_file}") + + set(shld_overlay_dsts + "${GENERATED_SHIELDS_DIR}/${shld}.overlay" + "${GENERATED_SHIELDS_DIR}/${shld}_${board_overlay_stem}.overlay" + "${GENERATED_SHIELDS_DIR}/${shld}_${board_overlay_stem}_${shield_overlay_stem}.overlay") + + foreach(src_conf ${shld_conf_srcs}) + # Search for shield/shield.conf file + if(EXISTS ${src_conf}) + list(APPEND shield_conf_files ${src_conf}) + endif() + endforeach() + + foreach(src_overlay dst_overlay IN ZIP_LISTS shld_overlay_srcs shld_overlay_dsts) + if (EXISTS ${src_overlay}) + execute_process(COMMAND + ${PYTHON_EXECUTABLE} + ${GEN_SHIELD_DERIVED_OVERLAY_SCRIPT} + "${src_overlay}" + "--shield-options=${shld_opts}" + "--output-filename=${dst_overlay}") + + list(APPEND shield_dts_files "${dst_overlay}") + endif() + endforeach() + endforeach() endif() diff --git a/doc/hardware/porting/shields.rst b/doc/hardware/porting/shields.rst index 6f3dff1be5fb802..14c2c144154f62f 100644 --- a/doc/hardware/porting/shields.rst +++ b/doc/hardware/porting/shields.rst @@ -17,12 +17,15 @@ under :zephyr_file:`boards/shields`: .. code-block:: none boards/shields/ + ├── shield.yml ├── .overlay ├── Kconfig.shield └── Kconfig.defconfig These files provides shield configuration as follows: +* ***shield.yml**: This file defines the name of the shield, its variant + information, and the information it accepts if parameterized. * **.overlay**: This file provides a shield description in devicetree format that is merged with the board's :ref:`devicetree ` before compilation. @@ -48,6 +51,100 @@ to provide a device nodelabel is the form _, for instance: ... }; +shield.yml format +***************** + +Shield parametrization +********************** + +The Zephyr shield framework supports parameterized configuration, allowing users to +customize shield behavior and connections directly from the command line. +This feature is particularly useful for multi-connector shields or when multiple +instances of the same shield need to coexist with different configurations. + +Overview of Shield Parametrization +================================== + +Shield parametrization extends the ``--shield`` option in the west build command to +accept key-value pairs that define configuration parameters. +These parameters can include connector names, I2C addresses, GPIO pins, and more. +Additionally, the framework supports default values, ensuring functionality +even when no explicit parameters are provided. + +Specifying Parameters +--------------------- + +Parameters are specified in the --shield option using the following syntax: + +:: + + [: