From 0115c47b698d15bee77c0f5834a4d2b06b0a9433 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 14 Jan 2019 16:11:15 +0100 Subject: [PATCH] cmake: dts: move to specifying shield on the command line Rather than specifying SHIELD via Kconfig, we move it to being specified via the command line, similar to board. So we can do: -DSHIELD=x_nucleo_iks01a1 or, for multiple shields: -DSHIELD="x_nucleo_iks01a1 frdm_kw41z" Following cmake change, update x_nucleo_iks01a1 sample in order not to enable CONFIG option anymore but set SHIELD cmake option. Last, update documentation to reflect this change. Signed-off-by: Erwan Gouriou Signed-off-by: Kumar Gala --- cmake/app/boilerplate.cmake | 110 ++++++++++++++++++ cmake/dts.cmake | 38 +----- cmake/extensions.cmake | 2 + cmake/usage/CMakeLists.txt | 2 + cmake/usage/usage.cmake | 10 +- doc/porting/shields.rst | 25 ++-- .../bluetooth/peripheral_hr/CMakeLists.txt | 10 ++ .../overlay-shield_frdm_kw41z.conf | 7 -- samples/bluetooth/peripheral_hr/sample.yaml | 7 +- .../shields/x_nucleo_iks01a1/CMakeLists.txt | 3 + samples/shields/x_nucleo_iks01a1/README.rst | 3 + samples/shields/x_nucleo_iks01a1/prj.conf | 10 +- samples/shields/x_nucleo_iks01a1/sample.yaml | 1 + 13 files changed, 163 insertions(+), 65 deletions(-) delete mode 100644 samples/bluetooth/peripheral_hr/overlay-shield_frdm_kw41z.conf diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake index 769499a1e57..6d7f628b354 100644 --- a/cmake/app/boilerplate.cmake +++ b/cmake/app/boilerplate.cmake @@ -186,6 +186,65 @@ message(STATUS "Selected BOARD ${BOARD}") # Store the selected board in the cache set(CACHED_BOARD ${BOARD} CACHE STRING "Selected board") +# The SHIELD can be set by 3 sources. Through environment variables, +# through the cmake CLI, and through CMakeLists.txt. +# +# CLI has the highest precedence, then comes environment variables, +# and then finally CMakeLists.txt. +# +# A user can ignore all the precedence rules if he simply always uses +# the same source. E.g. always specifies -DSHIELD= on the command line, +# always has an environment variable set, or always has a set(SHIELD +# foo) line in his CMakeLists.txt and avoids mixing sources. +# +# The selected SHIELD can be accessed through the variable 'SHIELD'. + +# Read out the cached shield value if present +get_property(cached_shield_value CACHE SHIELD PROPERTY VALUE) + +# There are actually 4 sources, the three user input sources, and the +# previously used value (CACHED_SHIELD). The previously used value has +# precedence, and if we detect that the user is trying to change the +# value we give him a warning about needing to clean the build +# directory to be able to change shields. + +set(shield_cli_argument ${cached_shield_value}) # Either new or old +if(shield_cli_argument STREQUAL CACHED_SHIELD) + # We already have a CACHED_SHIELD so there is no new input on the CLI + unset(shield_cli_argument) +endif() + +set(shield_app_cmake_lists ${SHIELD}) +if(cached_shield_value STREQUAL SHIELD) + # The app build scripts did not set a default, The SHIELD we are + # reading is the cached value from the CLI + unset(shield_app_cmake_lists) +endif() + +if(CACHED_SHIELD) + # Warn the user if it looks like he is trying to change the shield + # without cleaning first + if(shield_cli_argument) + if(NOT (CACHED_SHIELD STREQUAL shield_cli_argument)) + message(WARNING "The build directory must be cleaned pristinely when changing shields") + # TODO: Support changing shields without requiring a clean build + endif() + endif() + + set(SHIELD ${CACHED_SHIELD}) +elseif(shield_cli_argument) + set(SHIELD ${shield_cli_argument}) + +elseif(DEFINED ENV{SHIELD}) + set(SHIELD $ENV{SHIELD}) + +elseif(shield_app_cmake_lists) + set(SHIELD ${shield_app_cmake_lists}) +endif() + +# Store the selected shield in the cache +set(CACHED_SHIELD ${SHIELD} CACHE STRING "Selected shield") + # 'BOARD_ROOT' is a prioritized list of directories where boards may # be found. It always includes ${ZEPHYR_BASE} at the lowest priority. list(APPEND BOARD_ROOT ${ZEPHYR_BASE}) @@ -210,6 +269,48 @@ foreach(root ${BOARD_ROOT}) if(BOARD_DIR AND NOT (${root} STREQUAL ${ZEPHYR_BASE})) set(USING_OUT_OF_TREE_BOARD 1) endif() + + set(shield_dir ${root}/boards/shields) + if(DEFINED SHIELD) + string(REPLACE " " ";" SHIELD_AS_LIST "${SHIELD}") + endif() + # Match the .overlay files in the shield directories to make sure we are + # finding shields, e.g. x_nucleo_iks01a1/x_nucleo_iks01a1.overlay + file(GLOB_RECURSE shields_refs_list + RELATIVE ${shield_dir} + ${shield_dir}/*/*.overlay + ) + + # The above gives a list like + # x_nucleo_iks01a1/x_nucleo_iks01a1.overlay;x_nucleo_iks01a2/x_nucleo_iks01a2.overlay + # we construct a list of shield names by extracting file name and + # removing the extension. + foreach(shield_path ${shields_refs_list}) + get_filename_component(shield ${shield_path} NAME_WE) + list(APPEND SHIELD_LIST ${shield}) + endforeach() + + if(DEFINED SHIELD) + foreach(s ${SHIELD_AS_LIST}) + list(FIND SHIELD_LIST ${s} _idx) + if (NOT _idx EQUAL -1) + list(GET shields_refs_list ${_idx} s_path) + + # if shield config flag is on, add shield overlay to the shield overlays + # list and dts_fixup file to the shield fixup file + list(APPEND + shield_dts_files + ${shield_dir}/${s_path} + ) + list(APPEND + shield_dts_fixups + ${shield_dir}/${s}/dts_fixup.h + ) + else() + list(APPEND NOT_FOUND_SHIELD_LIST ${s}) + endif() + endforeach() + endif() endforeach() if(NOT BOARD_DIR) @@ -219,6 +320,15 @@ if(NOT BOARD_DIR) message(FATAL_ERROR "Invalid usage") endif() +if(DEFINED SHIELD AND DEFINED NOT_FOUND_SHIELD_LIST) + foreach (s ${NOT_FOUND_SHIELD_LIST}) + message("No shield named '${s}' found") + endforeach() + print_usage() + unset(CACHED_SHIELD CACHE) + message(FATAL_ERROR "Invalid usage") +endif() + get_filename_component(BOARD_ARCH_DIR ${BOARD_DIR} DIRECTORY) get_filename_component(BOARD_FAMILY ${BOARD_DIR} NAME) get_filename_component(ARCH ${BOARD_ARCH_DIR} NAME) diff --git a/cmake/dts.cmake b/cmake/dts.cmake index 073c52f7fd6..b1b76aa8a1e 100644 --- a/cmake/dts.cmake +++ b/cmake/dts.cmake @@ -18,44 +18,9 @@ set_ifndef(DTS_APP_INCLUDE ${APPLICATION_SOURCE_DIR}/dts) set(dts_files ${DTS_SOURCE} ${DTS_COMMON_OVERLAYS} + ${shield_dts_files} ) -# Parse boards/shields of each board root to generate the shield list -foreach(board_root ${BOARD_ROOT}) - set(shield_dir ${board_root}/boards/shields) - - # Match the .overlay files in the shield directories to make sure we are - # finding shields, e.g. x_nucleo_iks01a1/x_nucleo_iks01a1.overlay - file(GLOB_RECURSE shields_refs_list - RELATIVE ${shield_dir} - ${shield_dir}/*/*.overlay - ) - - # The above gives a list like - # x_nucleo_iks01a1/x_nucleo_iks01a1.overlay;x_nucleo_iks01a2/x_nucleo_iks01a2.overlay - # we construct a list of shield names by extracting file name and - # removing the extension. - foreach(shield_path ${shields_refs_list}) - get_filename_component(shield ${shield_path} NAME_WE) - - # Generate CONFIG flags matching each shield - string(TOUPPER "CONFIG_SHIELD_${shield}" shield_config) - - if(${shield_config}) - # if shield config flag is on, add shield overlay to the shield overlays - # list and dts_fixup file to the shield fixup file - list(APPEND - dts_files - ${shield_dir}/${shield_path} - ) - list(APPEND - dts_fixups - ${shield_dir}/${shield}/dts_fixup.h - ) - endif() - endforeach() -endforeach() - if(CONFIG_HAS_DTS) if(DTC_OVERLAY_FILE) @@ -155,6 +120,7 @@ if(CONFIG_HAS_DTS) ${DTS_BOARD_FIXUP_FILE} ${DTS_SOC_FIXUP_FILE} ${APPLICATION_SOURCE_DIR}/dts_fixup.h + ${shield_dts_fixups} ) foreach(fixup ${dts_fixups}) diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index 344b2812e67..a19b07329ee 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -1108,10 +1108,12 @@ endmacro() function(print_usage) message("see usage:") string(REPLACE ";" " " BOARD_ROOT_SPACE_SEPARATED "${BOARD_ROOT}") + string(REPLACE ";" " " SHIELD_LIST_SPACE_SEPARATED "${SHIELD_LIST}") execute_process( COMMAND ${CMAKE_COMMAND} -DBOARD_ROOT_SPACE_SEPARATED=${BOARD_ROOT_SPACE_SEPARATED} + -DSHIELD_LIST_SPACE_SEPARATED=${SHIELD_LIST_SPACE_SEPARATED} -P ${ZEPHYR_BASE}/cmake/usage/usage.cmake ) endfunction() diff --git a/cmake/usage/CMakeLists.txt b/cmake/usage/CMakeLists.txt index 85ad5d1cc60..9a1001de554 100644 --- a/cmake/usage/CMakeLists.txt +++ b/cmake/usage/CMakeLists.txt @@ -1,9 +1,11 @@ string(REPLACE ";" " " BOARD_ROOT_SPACE_SEPARATED "${BOARD_ROOT}") +string(REPLACE ";" " " SHIELD_LIST_SPACE_SEPARATED "${SHIELD_LIST}") add_custom_target( usage ${CMAKE_COMMAND} -DBOARD_ROOT_SPACE_SEPARATED=${BOARD_ROOT_SPACE_SEPARATED} + -DSHIELD_LIST_SPACE_SEPARATED=${SHIELD_LIST_SPACE_SEPARATED} -P ${CMAKE_CURRENT_SOURCE_DIR}/usage.cmake ) diff --git a/cmake/usage/usage.cmake b/cmake/usage/usage.cmake index 05b19f9cb86..34dbbbdde05 100644 --- a/cmake/usage/usage.cmake +++ b/cmake/usage/usage.cmake @@ -13,6 +13,7 @@ set(arch_list ) string(REPLACE " " ";" BOARD_ROOT "${BOARD_ROOT_SPACE_SEPARATED}") +string(REPLACE " " ";" SHIELD_LIST "${SHIELD_LIST_SPACE_SEPARATED}") foreach(arch ${arch_list}) foreach(root ${BOARD_ROOT}) @@ -60,11 +61,12 @@ message("Supported Boards:") message("") message(" To generate project files for one of the supported boards below, run:") message("") -message(" $ cmake -DBOARD= -Bpath/to/build_dir -Hpath/to/source_dir") +message(" $ cmake -DBOARD= [-DSHIELD=] -Bpath/to/build_dir -Hpath/to/source_dir") message("") message(" or") message("") message(" $ export BOARD=") +message(" $ export SHIELD= #optional") message(" $ cmake -Bpath/to/build_dir -Hpath/to/source_dir") message("") foreach(arch ${arch_list}) @@ -74,6 +76,12 @@ foreach(arch ${arch_list}) endforeach() endforeach() message("") +message("Supported Shields:") +message("") +foreach(shield ${SHIELD_LIST}) + message(" ${shield}") +endforeach() +message("") message("Build flags:") message("") message(" ${generator} VERBOSE=1 [targets] verbose build") diff --git a/doc/porting/shields.rst b/doc/porting/shields.rst index 7c261625a3e..e643595a87b 100644 --- a/doc/porting/shields.rst +++ b/doc/porting/shields.rst @@ -17,22 +17,11 @@ under :file:`/boards/shields`: .. code-block:: none boards/shields/ - ├── Kconfig.shield - ├── Kconfig.defconfig ├── .overlay └── dts_fixup.h These files provides shield configuration as follows: -* **Kconfig.shield**: This file defines the shield's config flag - (CONFIG_SHIELD_X). Applications use this flag to trigger the shield - configuration on top of the board configuration, enabling each shield - component or sensor driver. - -* **Kconfig.defconfig**: This file provides conditional configuration of - specific driver default configurations, offering flexibility for broad - board support. - * **.overlay**: This file provides a shield description in device tree format that is merged with the board's device tree information before compilation. @@ -74,9 +63,17 @@ introduced overriding node element: Shield activation ***************** -Activate support for a shield by enabling the corresponding Kconfig shield -option in the application's prj.conf file. +Activate support for a shield by adding the matching -DSHIELD arg to CMake +command + + .. zephyr-app-commands:: + :zephyr-app: your_app + :gen-args: -DSHIELD=x_nucleo_iks01a1 + :goals: build + + +Alternatively, it could be set by default in a project's CMakeLists.txt: .. code-block:: none - #CONFIG_SHIELD_X_NUCLEO_IKS01A2=y + set(SHIELD x_nucleo_iks01a1) diff --git a/samples/bluetooth/peripheral_hr/CMakeLists.txt b/samples/bluetooth/peripheral_hr/CMakeLists.txt index 28edde4b97c..04f10ca6936 100644 --- a/samples/bluetooth/peripheral_hr/CMakeLists.txt +++ b/samples/bluetooth/peripheral_hr/CMakeLists.txt @@ -1,4 +1,14 @@ cmake_minimum_required(VERSION 3.13.1) + +# Some boards could run this sample using frdm_kw41z shield, enforce +# -DSHIELD option in case they are used +if(BOARD STREQUAL mimxrt1020_evk OR + BOARD STREQUAL mimxrt1050_evk OR + BOARD STREQUAL mimxrt1060_evk OR + BOARD STREQUAL frdm_k64f) +set(SHIELD frdm_kw41z) +endif() + include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) project(peripheral_hr) diff --git a/samples/bluetooth/peripheral_hr/overlay-shield_frdm_kw41z.conf b/samples/bluetooth/peripheral_hr/overlay-shield_frdm_kw41z.conf deleted file mode 100644 index 1c6f93e315c..00000000000 --- a/samples/bluetooth/peripheral_hr/overlay-shield_frdm_kw41z.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2018, NXP -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SHIELD_FRDM_KW41Z=y diff --git a/samples/bluetooth/peripheral_hr/sample.yaml b/samples/bluetooth/peripheral_hr/sample.yaml index a882d5ac050..4beb080fcef 100644 --- a/samples/bluetooth/peripheral_hr/sample.yaml +++ b/samples/bluetooth/peripheral_hr/sample.yaml @@ -4,10 +4,5 @@ sample: tests: test: harness: bluetooth - platform_whitelist: qemu_cortex_m3 qemu_x86 - tags: bluetooth - test.overlay-shield_frdm_kw41z: - harness: bluetooth - extra_args: OVERLAY_CONFIG=overlay-shield_frdm_kw41z.conf - platform_whitelist: mimxrt1020_evk mimxrt1050_evk mimxrt1060_evk frdm_k64f + platform_whitelist: qemu_cortex_m3 qemu_x86 mimxrt1020_evk mimxrt1050_evk mimxrt1060_evk frdm_k64f tags: bluetooth diff --git a/samples/shields/x_nucleo_iks01a1/CMakeLists.txt b/samples/shields/x_nucleo_iks01a1/CMakeLists.txt index 02ab9fd6456..d4242783e01 100644 --- a/samples/shields/x_nucleo_iks01a1/CMakeLists.txt +++ b/samples/shields/x_nucleo_iks01a1/CMakeLists.txt @@ -1,5 +1,8 @@ cmake_minimum_required(VERSION 3.13.1) +# This sample is specific to x_nucleo_iks01a1 shield. Enforce -DSHIELD option +set(SHIELD x_nucleo_iks01a1) + include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) project(x_nucleo_iks01a1) diff --git a/samples/shields/x_nucleo_iks01a1/README.rst b/samples/shields/x_nucleo_iks01a1/README.rst index 8dd2f438d0f..406db5b2163 100644 --- a/samples/shields/x_nucleo_iks01a1/README.rst +++ b/samples/shields/x_nucleo_iks01a1/README.rst @@ -20,6 +20,9 @@ This sample communicates over I2C with the X-NUCLEO-IKS01A1 shield stacked on a board with an Arduino connector. The board's I2C must be configured for the I2C Arduino connector (both for pin muxing and device tree). +Please note that this sample can't be used with boards already supporting +one of the sensors available on the shield (such as disco_l475_iot1) as zephyr +does not yet support sensors multiple instances. References ********** diff --git a/samples/shields/x_nucleo_iks01a1/prj.conf b/samples/shields/x_nucleo_iks01a1/prj.conf index 305ffb25faa..c164f74a04c 100644 --- a/samples/shields/x_nucleo_iks01a1/prj.conf +++ b/samples/shields/x_nucleo_iks01a1/prj.conf @@ -1,2 +1,10 @@ CONFIG_STDOUT_CONSOLE=y -CONFIG_SHIELD_X_NUCLEO_IKS01A1=y +CONFIG_I2C=y +CONFIG_I2C_STM32_INTERRUPT=y +CONFIG_SENSOR=y +CONFIG_HTS221=y +CONFIG_LPS25HB=y +CONFIG_LSM6DS0=y +CONFIG_LIS3MDL=y +CONFIG_HTS221_TRIGGER_NONE=y +CONFIG_LIS3MDL_TRIGGER_NONE=y diff --git a/samples/shields/x_nucleo_iks01a1/sample.yaml b/samples/shields/x_nucleo_iks01a1/sample.yaml index bfddeae065b..c9aacb3e047 100644 --- a/samples/shields/x_nucleo_iks01a1/sample.yaml +++ b/samples/shields/x_nucleo_iks01a1/sample.yaml @@ -6,3 +6,4 @@ tests: harness: shield tags: shield depends_on: arduino_i2c + platform_exclude: disco_l475_iot1