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 <erwan.gouriou@linaro.org>
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
This commit is contained in:
Erwan Gouriou 2019-01-14 16:11:15 +01:00 committed by Kumar Gala
parent affc1ed253
commit 0115c47b69
13 changed files with 163 additions and 65 deletions

View file

@ -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)

View file

@ -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})

View file

@ -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()

View file

@ -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
)

View file

@ -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=<BOARD NAME> -Bpath/to/build_dir -Hpath/to/source_dir")
message(" $ cmake -DBOARD=<BOARD NAME> [-DSHIELD=<SHIELD NAME>] -Bpath/to/build_dir -Hpath/to/source_dir")
message("")
message(" or")
message("")
message(" $ export BOARD=<BOARD NAME>")
message(" $ export SHIELD=<SHIELD NAME> #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")

View file

@ -17,22 +17,11 @@ under :file:`/boards/shields`:
.. code-block:: none
boards/shields/<shield>
├── Kconfig.shield
├── Kconfig.defconfig
├── <shield>.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.
* **<shield>.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)

View file

@ -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)

View file

@ -1,7 +0,0 @@
#
# Copyright (c) 2018, NXP
#
# SPDX-License-Identifier: Apache-2.0
#
CONFIG_SHIELD_FRDM_KW41Z=y

View file

@ -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

View file

@ -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)

View file

@ -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
**********

View file

@ -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

View file

@ -6,3 +6,4 @@ tests:
harness: shield
tags: shield
depends_on: arduino_i2c
platform_exclude: disco_l475_iot1