diff --git a/boards/arc/arduino_101_sss/board.cmake b/boards/arc/arduino_101_sss/board.cmake index b6b06e83e05..59a632d55cf 100644 --- a/boards/arc/arduino_101_sss/board.cmake +++ b/boards/arc/arduino_101_sss/board.cmake @@ -1,29 +1,14 @@ if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU}) set(BOARD_FLASH_RUNNER dfu-util) - - set(DFUUTIL_PID 8087:0aba) - set(DFUUTIL_ALT sensor_core) - set(DFUUTIL_IMG ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}) - - set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - DFUUTIL_PID - DFUUTIL_ALT - DFUUTIL_IMG - ) else() set(BOARD_FLASH_RUNNER openocd) endif() set(BOARD_DEBUG_RUNNER openocd) -set(OPENOCD_PRE_CMD "targets 1") -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(GDB_PORT 3334) +board_runner_args(dfu-util "--pid=8087:0aba" "--alt=sensor_core") +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"" "--gdb-port=3334") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD - GDB_PORT - ) +include($ENV{ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arc/em_starterkit/board.cmake b/boards/arc/em_starterkit/board.cmake index 8af72db090b..02525f205af 100644 --- a/boards/arc/em_starterkit/board.cmake +++ b/boards/arc/em_starterkit/board.cmake @@ -1,10 +1,4 @@ +# TODO: can this board just use the usual openocd runner? set(BOARD_FLASH_RUNNER em-starterkit) set(BOARD_DEBUG_RUNNER em-starterkit) - -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD - ) +board_finalize_runner_args(em-starterkit) diff --git a/boards/arc/panther_ss/board.cmake b/boards/arc/panther_ss/board.cmake index 09a364c39a7..6575ce13f60 100644 --- a/boards/arc/panther_ss/board.cmake +++ b/boards/arc/panther_ss/board.cmake @@ -1,7 +1,4 @@ +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"") +set(OPENOCD_USE_LOAD_IMAGE NO) include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) - -set(OPENOCD_PRE_CMD "targets 1") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - ) diff --git a/boards/arc/quark_se_c1000_ss_devboard/board.cmake b/boards/arc/quark_se_c1000_ss_devboard/board.cmake index 64a3fc1a704..65010c00b96 100644 --- a/boards/arc/quark_se_c1000_ss_devboard/board.cmake +++ b/boards/arc/quark_se_c1000_ss_devboard/board.cmake @@ -1,8 +1,3 @@ +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"") include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) - -set(OPENOCD_PRE_CMD "targets 1") -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - ) diff --git a/boards/arm/96b_carbon/board.cmake b/boards/arm/96b_carbon/board.cmake index 055fbc9e45f..ca9346ea8ec 100644 --- a/boards/arm/96b_carbon/board.cmake +++ b/boards/arm/96b_carbon/board.cmake @@ -1,13 +1,4 @@ -set(BOARD_FLASH_RUNNER dfu-util) +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0") +board_runner_args(dfu-util "--dfuse-addr=${CONFIG_FLASH_BASE_ADDRESS}") -set(DFUUTIL_PID 0483:df11) -set(DFUUTIL_ALT 0) -set(DFUUTIL_IMG ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}) -set(DFUUTIL_DFUSE_ADDR ${CONFIG_FLASH_BASE_ADDRESS}) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - DFUUTIL_PID - DFUUTIL_ALT - DFUUTIL_IMG - DFUUTIL_DFUSE_ADDR - ) +include($ENV{ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) diff --git a/boards/arm/96b_nitrogen/board.cmake b/boards/arm/96b_nitrogen/board.cmake index 419d19a88b6..5c3963576e5 100644 --- a/boards/arm/96b_nitrogen/board.cmake +++ b/boards/arm/96b_nitrogen/board.cmake @@ -1,8 +1,2 @@ -set(BOARD_FLASH_RUNNER pyocd) -set(BOARD_DEBUG_RUNNER pyocd) - -set(PYOCD_TARGET nrf52) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - PYOCD_TARGET - ) +board_runner_args(pyocd "--target=nrf52") +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/arduino_101_ble/board.cmake b/boards/arm/arduino_101_ble/board.cmake index 73aef2bc903..3c4ba4a1cb4 100644 --- a/boards/arm/arduino_101_ble/board.cmake +++ b/boards/arm/arduino_101_ble/board.cmake @@ -1,13 +1,2 @@ -if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU}) - set(BOARD_FLASH_RUNNER dfu-util) - - set(DFUUTIL_PID 8087:0aba) - set(DFUUTIL_ALT ble_core) - set(DFUUTIL_IMG ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}) - - set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - DFUUTIL_PID - DFUUTIL_ALT - DFUUTIL_IMG - ) -endif() +board_runner_args(dfu-util "--pid=8087:0aba" "--alt=ble_core") +include($ENV{ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) diff --git a/boards/arm/arduino_due/board.cmake b/boards/arm/arduino_due/board.cmake index 264e10db9ee..8e7c172d405 100644 --- a/boards/arm/arduino_due/board.cmake +++ b/boards/arm/arduino_due/board.cmake @@ -1 +1 @@ -set(BOARD_FLASH_RUNNER bossac) +include($ENV{ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/bbc_microbit/board.cmake b/boards/arm/bbc_microbit/board.cmake index 15a2fb0675b..eeb7c3212a5 100644 --- a/boards/arm/bbc_microbit/board.cmake +++ b/boards/arm/bbc_microbit/board.cmake @@ -1,8 +1,2 @@ -set(BOARD_FLASH_RUNNER pyocd) -set(BOARD_DEBUG_RUNNER pyocd) - -set(PYOCD_TARGET nrf51) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - PYOCD_TARGET - ) +board_runner_args(pyocd "--target=nrf51") +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/frdm_k64f/board.cmake b/boards/arm/frdm_k64f/board.cmake index bde2ef45107..ac4f05e91f0 100644 --- a/boards/arm/frdm_k64f/board.cmake +++ b/boards/arm/frdm_k64f/board.cmake @@ -7,14 +7,9 @@ elseif(OPENSDA_FW STREQUAL daplink) set_ifndef(BOARD_FLASH_RUNNER pyocd) endif() -set(JLINK_DEVICE MK64FN1M0xxx12) -set(PYOCD_TARGET k64f) -set(OPENOCD_LOAD_CMD "flash write_image erase ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") +board_runner_args(jlink "--device=MK64FN1M0xxx12") +board_runner_args(pyocd "--target=k64f") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - PYOCD_TARGET - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD - ) +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/frdm_kl25z/board.cmake b/boards/arm/frdm_kl25z/board.cmake index e794ba492a9..a3fe31a58d6 100644 --- a/boards/arm/frdm_kl25z/board.cmake +++ b/boards/arm/frdm_kl25z/board.cmake @@ -7,10 +7,8 @@ elseif(OPENSDA_FW STREQUAL daplink) set_ifndef(BOARD_FLASH_RUNNER pyocd) endif() -set(JLINK_DEVICE MKL25Z128xxx4) -set(PYOCD_TARGET kl25z) +board_runner_args(jlink "--device=MKL25Z128xxx4") +board_runner_args(pyocd "--target=kl25z") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - PYOCD_TARGET - ) +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/frdm_kw41z/board.cmake b/boards/arm/frdm_kw41z/board.cmake index 0d8876cbe14..19e83a6a517 100644 --- a/boards/arm/frdm_kw41z/board.cmake +++ b/boards/arm/frdm_kw41z/board.cmake @@ -7,10 +7,8 @@ elseif(OPENSDA_FW STREQUAL daplink) set_ifndef(BOARD_FLASH_RUNNER pyocd) endif() -set(JLINK_DEVICE MKW41Z512xxx4) -set(PYOCD_TARGET kw41z4) +board_runner_args(jlink "--device=MKW41Z512xxx4") +board_runner_args(pyocd "--target=kw41z4") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - PYOCD_TARGET - ) +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/hexiwear_k64/board.cmake b/boards/arm/hexiwear_k64/board.cmake index 2d4b0d2db4f..7e56df6be54 100644 --- a/boards/arm/hexiwear_k64/board.cmake +++ b/boards/arm/hexiwear_k64/board.cmake @@ -7,10 +7,8 @@ elseif(OPENSDA_FW STREQUAL daplink) set_ifndef(BOARD_FLASH_RUNNER pyocd) endif() -set(JLINK_DEVICE MK64FN1M0xxx12) -set(PYOCD_TARGET k64f) +board_runner_args(pyocd "--target=k64f") +board_runner_args(jlink "--device=MK64FN1M0xxx12") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - PYOCD_TARGET - ) +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/hexiwear_kw40z/board.cmake b/boards/arm/hexiwear_kw40z/board.cmake index bff80442bcf..1981474ac94 100644 --- a/boards/arm/hexiwear_kw40z/board.cmake +++ b/boards/arm/hexiwear_kw40z/board.cmake @@ -7,10 +7,8 @@ elseif(OPENSDA_FW STREQUAL daplink) set_ifndef(BOARD_FLASH_RUNNER pyocd) endif() -set(JLINK_DEVICE MKW40Z160xxx4) -set(PYOCD_TARGET kw40z4) +board_runner_args(jlink "--device=MKW40Z160xxx4") +board_runner_args(pyocd "--target=kw40z4") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - PYOCD_TARGET - ) +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1050_evk/board.cmake b/boards/arm/mimxrt1050_evk/board.cmake index 8e6f095f8bb..ae020d5a669 100644 --- a/boards/arm/mimxrt1050_evk/board.cmake +++ b/boards/arm/mimxrt1050_evk/board.cmake @@ -4,14 +4,5 @@ # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - set_ifndef(BOARD_DEBUG_RUNNER jlink) -endif() - -set(JLINK_DEVICE Cortex-M7) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - ) +board_runner_args(jlink "--device=Cortex-M7") +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf51_pca10028/board.cmake b/boards/arm/nrf51_pca10028/board.cmake index 76f17e0fbb2..c360db62951 100644 --- a/boards/arm/nrf51_pca10028/board.cmake +++ b/boards/arm/nrf51_pca10028/board.cmake @@ -1,7 +1,2 @@ -set(BOARD_FLASH_RUNNER nrfjprog) - -set(NRF_FAMILY NRF51) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - NRF_FAMILY - ) +board_runner_args(nrfjprog "--nrf-family=NRF51") +include($ENV{ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf51_vbluno51/board.cmake b/boards/arm/nrf51_vbluno51/board.cmake index 15a2fb0675b..eeb7c3212a5 100644 --- a/boards/arm/nrf51_vbluno51/board.cmake +++ b/boards/arm/nrf51_vbluno51/board.cmake @@ -1,8 +1,2 @@ -set(BOARD_FLASH_RUNNER pyocd) -set(BOARD_DEBUG_RUNNER pyocd) - -set(PYOCD_TARGET nrf51) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - PYOCD_TARGET - ) +board_runner_args(pyocd "--target=nrf51") +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/nrf52840_pca10056/board.cmake b/boards/arm/nrf52840_pca10056/board.cmake index 623dacf10a9..a494475a461 100644 --- a/boards/arm/nrf52840_pca10056/board.cmake +++ b/boards/arm/nrf52840_pca10056/board.cmake @@ -1,6 +1,2 @@ -set(BOARD_FLASH_RUNNER nrfjprog) -set(NRF_FAMILY NRF52) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - NRF_FAMILY - ) +board_runner_args(nrfjprog "--nrf-family=NRF52") +include($ENV{ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52_blenano2/board.cmake b/boards/arm/nrf52_blenano2/board.cmake index 419d19a88b6..5c3963576e5 100644 --- a/boards/arm/nrf52_blenano2/board.cmake +++ b/boards/arm/nrf52_blenano2/board.cmake @@ -1,8 +1,2 @@ -set(BOARD_FLASH_RUNNER pyocd) -set(BOARD_DEBUG_RUNNER pyocd) - -set(PYOCD_TARGET nrf52) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - PYOCD_TARGET - ) +board_runner_args(pyocd "--target=nrf52") +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/nrf52_pca10040/board.cmake b/boards/arm/nrf52_pca10040/board.cmake index 01306564e75..a494475a461 100644 --- a/boards/arm/nrf52_pca10040/board.cmake +++ b/boards/arm/nrf52_pca10040/board.cmake @@ -1,7 +1,2 @@ -set(BOARD_FLASH_RUNNER nrfjprog) - -set(NRF_FAMILY NRF52) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - NRF_FAMILY - ) +board_runner_args(nrfjprog "--nrf-family=NRF52") +include($ENV{ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52_vbluno52/board.cmake b/boards/arm/nrf52_vbluno52/board.cmake index 419d19a88b6..5c3963576e5 100644 --- a/boards/arm/nrf52_vbluno52/board.cmake +++ b/boards/arm/nrf52_vbluno52/board.cmake @@ -1,8 +1,2 @@ -set(BOARD_FLASH_RUNNER pyocd) -set(BOARD_DEBUG_RUNNER pyocd) - -set(PYOCD_TARGET nrf52) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - PYOCD_TARGET - ) +board_runner_args(pyocd "--target=nrf52") +include($ENV{ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/sam_e70_xplained/board.cmake b/boards/arm/sam_e70_xplained/board.cmake index a88846709b4..fb4b3817308 100644 --- a/boards/arm/sam_e70_xplained/board.cmake +++ b/boards/arm/sam_e70_xplained/board.cmake @@ -1,7 +1,3 @@ +set(POST_VERIFY atsamv gpnvm set 1) +board_runner_args(openocd "--cmd-post-verify=\"${POST_VERIFY}\"") include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) - -set(OPENOCD_POST_CMD "atsamv gpnvm set 1") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_POST_CMD - ) diff --git a/boards/arm/usb_kw24d512/board.cmake b/boards/arm/usb_kw24d512/board.cmake index bf1424e59a5..fe85ec46537 100644 --- a/boards/arm/usb_kw24d512/board.cmake +++ b/boards/arm/usb_kw24d512/board.cmake @@ -1,7 +1,3 @@ -set(BOARD_DEBUG_RUNNER jlink) +board_runner_args(jlink "--device=MKW24D512xxx5") -set(JLINK_DEVICE MKW24D512xxx5) - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - JLINK_DEVICE - ) +include($ENV{ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/common/bossac.board.cmake b/boards/common/bossac.board.cmake new file mode 100644 index 00000000000..6c4cad0adb9 --- /dev/null +++ b/boards/common/bossac.board.cmake @@ -0,0 +1,2 @@ +set_ifndef(BOARD_FLASH_RUNNER bossac) +board_finalize_runner_args(bossac) # No default arguments to provide. diff --git a/boards/common/dfu-util.board.cmake b/boards/common/dfu-util.board.cmake new file mode 100644 index 00000000000..f41cf3a9036 --- /dev/null +++ b/boards/common/dfu-util.board.cmake @@ -0,0 +1,2 @@ +set_ifndef(BOARD_FLASH_RUNNER dfu-util) +board_finalize_runner_args(dfu-util) # No default arguments to provide. diff --git a/boards/common/esp32.board.cmake b/boards/common/esp32.board.cmake new file mode 100644 index 00000000000..81b2e812af7 --- /dev/null +++ b/boards/common/esp32.board.cmake @@ -0,0 +1,12 @@ +set(BOARD_FLASH_RUNNER esp32) + +if(NOT DEFINED ESP_IDF_PATH) + if($ENV{ESP_IDF_PATH}) + message(WARNING "Setting ESP_IDF_PATH in the environment is deprecated. Use cmake -DESP_IDF_PATH=... instead.") + set(ESP_IDF_PATH $ENV{ESP_IDF_PATH}) + endif() +endif() + +assert(ESP_IDF_PATH "ESP_IDF_PATH is not set") + +board_finalize_runner_args(esp32 "--esp-idf-path=${ESP_IDF_PATH}") diff --git a/boards/common/jlink.board.cmake b/boards/common/jlink.board.cmake new file mode 100644 index 00000000000..cb3f5ff832b --- /dev/null +++ b/boards/common/jlink.board.cmake @@ -0,0 +1,2 @@ +set_ifndef(BOARD_DEBUG_RUNNER jlink) +board_finalize_runner_args(jlink) # No default arguments to provide. diff --git a/boards/common/nios2.board.cmake b/boards/common/nios2.board.cmake new file mode 100644 index 00000000000..dec5ee824d1 --- /dev/null +++ b/boards/common/nios2.board.cmake @@ -0,0 +1,7 @@ +set_ifndef(BOARD_FLASH_RUNNER nios2) +set_ifndef(BOARD_DEBUG_RUNNER nios2) + +board_finalize_runner_args(nios2 + # TODO: merge this script into nios2.py + "--quartus-flash=$ENV{ZEPHYR_BASE}/scripts/support/quartus-flash.py" + ) diff --git a/boards/common/nrfjprog.board.cmake b/boards/common/nrfjprog.board.cmake new file mode 100644 index 00000000000..f68689636d6 --- /dev/null +++ b/boards/common/nrfjprog.board.cmake @@ -0,0 +1,2 @@ +set_ifndef(BOARD_FLASH_RUNNER nrfjprog) +board_finalize_runner_args(nrfjprog) # No default arguments to provide. diff --git a/boards/common/openocd.board.cmake b/boards/common/openocd.board.cmake index b2a31b2a1b1..6ea17fbec0d 100644 --- a/boards/common/openocd.board.cmake +++ b/boards/common/openocd.board.cmake @@ -1,10 +1,31 @@ -set(BOARD_FLASH_RUNNER openocd) -set(BOARD_DEBUG_RUNNER openocd) +set_ifndef(BOARD_FLASH_RUNNER openocd) +set_ifndef(BOARD_DEBUG_RUNNER openocd) -set(OPENOCD_LOAD_CMD "flash write_image erase ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") +# "load_image" or "flash write_image erase"? +if(CONFIG_X86 OR CONFIG_ARC) + set_ifndef(OPENOCD_USE_LOAD_IMAGE YES) +endif() +if(OPENOCD_USE_LOAD_IMAGE) + set_ifndef(OPENOCD_FLASH load_image) +else() + set_ifndef(OPENOCD_FLASH flash write_image erase) +endif() -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD +# zephyr.bin, or something else? +set_ifndef(OPENOCD_IMAGE "${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}") + +# CONFIG_FLASH_BASE_ADDRESS, or something else? +if(NOT DEFINED OPENOCD_ADDRESS) + # This can't use set_ifndef() because CONFIG_FLASH_BASE_ADDRESS is + # the empty string on some targets, which causes set_ifndef() to + # choke. + set(OPENOCD_ADDRESS "${CONFIG_FLASH_BASE_ADDRESS}") +endif() + +set(OPENOCD_CMD_LOAD_DEFAULT ${OPENOCD_FLASH} ${OPENOCD_IMAGE} ${OPENOCD_ADDRESS}) +set(OPENOCD_CMD_VERIFY_DEFAULT verify_image ${OPENOCD_IMAGE} ${OPENOCD_ADDRESS}) + +board_finalize_runner_args(openocd + "--cmd-load=\"${OPENOCD_CMD_LOAD_DEFAULT}\"" + "--cmd-verify=\"${OPENOCD_CMD_VERIFY_DEFAULT}\"" ) diff --git a/boards/common/pyocd.board.cmake b/boards/common/pyocd.board.cmake new file mode 100644 index 00000000000..9a2f45f7c43 --- /dev/null +++ b/boards/common/pyocd.board.cmake @@ -0,0 +1,3 @@ +set_ifndef(BOARD_FLASH_RUNNER pyocd) +set_ifndef(BOARD_DEBUG_RUNNER pyocd) +board_finalize_runner_args(pyocd) # No default arguments to provide. diff --git a/boards/nios2/altera_max10/board.cmake b/boards/nios2/altera_max10/board.cmake index ad4d1d6e4d2..266bc0db166 100644 --- a/boards/nios2/altera_max10/board.cmake +++ b/boards/nios2/altera_max10/board.cmake @@ -1,4 +1,2 @@ -set(BOARD_FLASH_RUNNER nios2) -set(BOARD_DEBUG_RUNNER nios2) -set(NIOS2_CPU_SOF $ENV{ZEPHYR_BASE}/arch/nios2/soc/nios2f-zephyr/cpu/ghrd_10m50da.sof) -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS NIOS2_CPU_SOF) +board_runner_args(nios2 "--cpu-sof=$ENV{ZEPHYR_BASE}/arch/nios2/soc/nios2f-zephyr/cpu/ghrd_10m50da.sof") +include($ENV{ZEPHYR_BASE}/boards/common/nios2.board.cmake) diff --git a/boards/x86/arduino_101/board.cmake b/boards/x86/arduino_101/board.cmake index 98ace6be600..6f3ddab3bbe 100644 --- a/boards/x86/arduino_101/board.cmake +++ b/boards/x86/arduino_101/board.cmake @@ -1,27 +1,12 @@ if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU}) set(BOARD_FLASH_RUNNER dfu-util) - - set(DFUUTIL_PID 8087:0aba) - set(DFUUTIL_ALT x86_app) - set(DFUUTIL_IMG ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}) - - set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - DFUUTIL_PID - DFUUTIL_ALT - DFUUTIL_IMG - ) -else() - set(BOARD_FLASH_RUNNER openocd) endif() set(BOARD_DEBUG_RUNNER openocd) -set(OPENOCD_PRE_CMD "targets 1") -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") +board_runner_args(dfu-util "--pid=8087:0aba" "--alt=x86_app") +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD - ) +include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) diff --git a/boards/x86/panther/board.cmake b/boards/x86/panther/board.cmake index e21d41ec0da..1496ef4b910 100644 --- a/boards/x86/panther/board.cmake +++ b/boards/x86/panther/board.cmake @@ -1,12 +1,4 @@ -set(BOARD_FLASH_RUNNER openocd) -set(BOARD_DEBUG_RUNNER openocd) - -set(OPENOCD_PRE_CMD "targets 1") -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_PHYS_LOAD_ADDR}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_PHYS_LOAD_ADDR}") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD - ) +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"") +set(OPENOCD_ADDRESS ${CONFIG_PHYS_LOAD_ADDR}) +include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/x86/quark_d2000_crb/board.cmake b/boards/x86/quark_d2000_crb/board.cmake index 682155a9772..2b06911ef78 100644 --- a/boards/x86/quark_d2000_crb/board.cmake +++ b/boards/x86/quark_d2000_crb/board.cmake @@ -1,7 +1 @@ include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) - -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_LOAD_CMD - ) diff --git a/boards/x86/quark_se_c1000_devboard/board.cmake b/boards/x86/quark_se_c1000_devboard/board.cmake index 729f163e454..65010c00b96 100644 --- a/boards/x86/quark_se_c1000_devboard/board.cmake +++ b/boards/x86/quark_se_c1000_devboard/board.cmake @@ -1,9 +1,3 @@ +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"") include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) - -set(OPENOCD_PRE_CMD "targets 1") -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") - -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - OPENOCD_LOAD_CMD - ) diff --git a/boards/x86/tinytile/board.cmake b/boards/x86/tinytile/board.cmake index 98ace6be600..6f3ddab3bbe 100644 --- a/boards/x86/tinytile/board.cmake +++ b/boards/x86/tinytile/board.cmake @@ -1,27 +1,12 @@ if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU}) set(BOARD_FLASH_RUNNER dfu-util) - - set(DFUUTIL_PID 8087:0aba) - set(DFUUTIL_ALT x86_app) - set(DFUUTIL_IMG ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}) - - set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - DFUUTIL_PID - DFUUTIL_ALT - DFUUTIL_IMG - ) -else() - set(BOARD_FLASH_RUNNER openocd) endif() set(BOARD_DEBUG_RUNNER openocd) -set(OPENOCD_PRE_CMD "targets 1") -set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") -set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}") +board_runner_args(dfu-util "--pid=8087:0aba" "--alt=x86_app") +set(PRE_LOAD targets 1) +board_runner_args(openocd "--cmd-pre-load=\"${PRE_LOAD}\"") -set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS - OPENOCD_PRE_CMD - OPENOCD_LOAD_CMD - OPENOCD_VERIFY_CMD - ) +include($ENV{ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include($ENV{ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) diff --git a/boards/xtensa/esp32/board.cmake b/boards/xtensa/esp32/board.cmake index 52d3449adf2..71595bf2439 100644 --- a/boards/xtensa/esp32/board.cmake +++ b/boards/xtensa/esp32/board.cmake @@ -1 +1 @@ -set(BOARD_FLASH_RUNNER esp32) +include($ENV{ZEPHYR_BASE}/boards/common/esp32.board.cmake) diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake index 484c211ceb9..dffda553f1f 100644 --- a/cmake/app/boilerplate.cmake +++ b/cmake/app/boilerplate.cmake @@ -244,9 +244,3 @@ Object files that are generated after Zephyr has been linked once.\ May include isr_tables.c etc." ) set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "") - -define_property(GLOBAL PROPERTY FLASH_SCRIPT_ENV_VARS - BRIEF_DOCS "Environment variables to pass to the flash/debug script" - FULL_DOCS "Environment variables to pass to the flash/debug script" - ) -set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "") diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index 179b2e96fb4..a1a1219c1f0 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -8,6 +8,7 @@ include(CheckCXXCompilerFlag) # 1.1. zephyr_* # 1.2. zephyr_library_* # 1.3. generate_inc_* +# 1.4. board_* # 2. Kconfig-aware extensions # 2.1 *_if_kconfig # 2.2 Misc @@ -435,6 +436,61 @@ function(zephyr_append_cmake_library library) set_property(GLOBAL APPEND PROPERTY ZEPHYR_LIBS ${library}) endfunction() +# 1.4. board_* +# +# This section is for extensions which control Zephyr's board runners +# from the build system. The Zephyr build system has targets for +# flashing and debugging supported boards. These are wrappers around a +# "runner" Python package that is part of Zephyr. This section +# provides glue between CMake and the runner invocation script, +# zephyr_flash_debug.py. + +# This function is intended for board.cmake files. +# +# Usage: +# board_runner_args(runner "--some-arg=val1" "--another-arg=val2") +# +# Will ensure the command line to zephyr_flash_debug.py contains: +# --some-arg=val1 --another-arg=val2 +# +# in the flash, debug, and debugserver target recipes, as +# appropriate. These settings will override any defaults provided by +# the build system. +function(board_runner_args runner) + string(MAKE_C_IDENTIFIER ${runner} runner_id) + # Note the "_EXPLICIT_" here, and see below. + set_property(GLOBAL APPEND PROPERTY BOARD_RUNNER_ARGS_EXPLICIT_${runner_id} ${ARGN}) +endfunction() + +# This function is intended for internal use by +# boards/common/runner.board.cmake files. +# +# Basic usage: +# board_finalize_runner_args(runner) +# +# This ensures the build system captures all arguments added in any +# board_runner_args() calls. +# +# Extended usage: +# board_runner_args(runner "--some-arg=default-value") +# +# This provides common or default values for arguments. These are +# placed before board_runner_args() calls, so they generally take +# precedence, except for arguments which can be given multiple times +# (use these with caution). +function(board_finalize_runner_args runner) + string(MAKE_C_IDENTIFIER ${runner} runner_id) + get_property(explicit GLOBAL PROPERTY "BOARD_RUNNER_ARGS_EXPLICIT_${runner_id}") + # Note no _EXPLICIT_ here. This property contains the final list. + set_property(GLOBAL APPEND PROPERTY BOARD_RUNNER_ARGS_${runner_id} + # Default arguments from the common runner file come first. + ${ARGN} + # Arguments explicitly given with board_runner_args() come + # last, so they take precedence. + ${explicit} + ) +endfunction() + ######################################################## # 2. Kconfig-aware extensions ######################################################## diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 90e067f3a84..153a1ea3f62 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -1,36 +1,31 @@ assert_not(FLASH_SCRIPT "FLASH_SCRIPT has been removed; use BOARD_FLASH_RUNNER") assert_not(DEBUG_SCRIPT "DEBUG_SCRIPT has been removed; use BOARD_DEBUG_RUNNER") -get_property(ENV_VARS GLOBAL PROPERTY FLASH_SCRIPT_ENV_VARS) - -set(ENV_VARS_FORMATTED "") -foreach(env_var ${ENV_VARS}) - list(APPEND ENV_VARS_FORMATTED - ${env_var}=${${env_var}} - ) -endforeach() - -list(APPEND ENV_VARS_FORMATTED - O=${PROJECT_BINARY_DIR} - KERNEL_ELF_NAME=${KERNEL_ELF_NAME} - KERNEL_HEX_NAME=${KERNEL_HEX_NAME} - KERNEL_BIN_NAME=${KERNEL_BIN_NAME} - BOARD_DIR=${BOARD_DIR} - GDB=${CMAKE_GDB} - OPENOCD_DEFAULT_PATH=${OPENOCD_DEFAULT_PATH} - OPENOCD=${OPENOCD} +set(RUNNER_ARGS_COMMON + # Required: + "--board-dir=${BOARD_DIR}" + "--kernel-elf=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" + "--kernel-hex=${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" + "--kernel-bin=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" + # Optional, but so often needed that they're provided by default: + # (TODO: revisit whether we really want these here) + "--gdb=${CMAKE_GDB}" + "--openocd=${OPENOCD}" + "--openocd-search=${OPENOCD_DEFAULT_PATH}" ) foreach(target flash debug debugserver) + string(TOUPPER "${target}" target_upper) + if(target STREQUAL flash) set(comment "Flashing ${BOARD}") - set(runner ${BOARD_FLASH_RUNNER}) + set(runner "${BOARD_FLASH_RUNNER}") elseif(target STREQUAL debug) set(comment "Debugging ${BOARD}") - set(runner ${BOARD_DEBUG_RUNNER}) + set(runner "${BOARD_DEBUG_RUNNER}") elseif(target STREQUAL debugserver) set(comment "Debugging ${BOARD}") - set(runner ${BOARD_DEBUG_RUNNER}) + set(runner "${BOARD_DEBUG_RUNNER}") if(EMU_PLATFORM) # cmake/qemu/CMakeLists.txt will add a debugserver target for # emulation platforms, so we don't add one here @@ -39,13 +34,18 @@ foreach(target flash debug debugserver) endif() if(runner) + # E.g. runner_ident = dfu_util (note the underscore), etc. + string(MAKE_C_IDENTIFIER "${runner}" runner_ident) + # E.g. args = BOARD_RUNNER_ARGS_openocd, BOARD_RUNNER_ARGS_dfu_util, etc. + get_property(args GLOBAL PROPERTY "BOARD_RUNNER_ARGS_${runner_ident}") set(cmd ${CMAKE_COMMAND} -E env - ${ENV_VARS_FORMATTED} ${PYTHON_EXECUTABLE} $ENV{ZEPHYR_BASE}/scripts/support/zephyr_flash_debug.py ${runner} ${target} + ${RUNNER_ARGS_COMMON} + ${args} DEPENDS ${logical_target_for_zephyr_elf} WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} ) diff --git a/scripts/support/runner/arc.py b/scripts/support/runner/arc.py index 9f5e5bf1489..4b0a8be2d79 100644 --- a/scripts/support/runner/arc.py +++ b/scripts/support/runner/arc.py @@ -1,14 +1,13 @@ # Copyright (c) 2017 Linaro Limited. +# Copyright (c) 2017 Open Source Foundries Limited. # # SPDX-License-Identifier: Apache-2.0 '''ARC architecture-specific runners.''' from os import path -import os -import shlex -from .core import ZephyrBinaryRunner, get_env_or_bail +from .core import ZephyrBinaryRunner DEFAULT_ARC_TCL_PORT = 6333 DEFAULT_ARC_TELNET_PORT = 4444 @@ -26,22 +25,19 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): # # TODO: exit immediately when flashing is done, leaving Zephyr running. - def __init__(self, elf, zephyr_base, board_dir, - gdb, openocd='openocd', extra_init=None, default_path=None, - tui=None, tcl_port=DEFAULT_ARC_TCL_PORT, + def __init__(self, board_dir, elf, gdb, + openocd='openocd', search=None, + tui=False, tcl_port=DEFAULT_ARC_TCL_PORT, telnet_port=DEFAULT_ARC_TELNET_PORT, gdb_port=DEFAULT_ARC_GDB_PORT, debug=False): super(EmStarterKitBinaryRunner, self).__init__(debug=debug) - self.elf = elf - self.zephyr_base = zephyr_base self.board_dir = board_dir - self.gdb = gdb + self.elf = elf + self.gdb_cmd = [gdb] + (['-tui'] if tui else []) search_args = [] - if default_path is not None: - search_args = ['-s', default_path] + if search is not None: + search_args = ['-s', search] self.openocd_cmd = [openocd] + search_args - self.extra_init = extra_init if extra_init is not None else [] - self.tui = tui self.tcl_port = tcl_port self.telnet_port = telnet_port self.gdb_port = gdb_port @@ -50,57 +46,29 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): def name(cls): return 'em-starterkit' - def create_from_env(command, debug): - '''Create runner from environment. + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--tui', default=False, action='store_true', + help='if given, GDB uses -tui') + parser.add_argument('--tcl-port', default=DEFAULT_ARC_TCL_PORT, + help='openocd TCL port, defaults to 6333') + parser.add_argument('--telnet-port', default=DEFAULT_ARC_TELNET_PORT, + help='openocd telnet port, defaults to 4444') + parser.add_argument('--gdb-port', default=DEFAULT_ARC_GDB_PORT, + help='openocd gdb port, defaults to 3333') - Required: - - - O: build output directory - - KERNEL_ELF_NAME: zephyr kernel binary in ELF format - - ZEPHYR_BASE: zephyr Git repository base directory - - BOARD_DIR: board directory - - GDB: gdb executable - - Optional: - - - OPENOCD: path to openocd, defaults to openocd - - OPENOCD_EXTRA_INIT: initialization command for GDB server - - OPENOCD_DEFAULT_PATH: openocd search path to use - - TUI: if present, passed to gdb server used to flash - - TCL_PORT: openocd TCL port, defaults to 6333 - - TELNET_PORT: openocd telnet port, defaults to 4444 - - GDB_PORT: openocd gdb port, defaults to 3333 - ''' - elf = path.join(get_env_or_bail('O'), - get_env_or_bail('KERNEL_ELF_NAME')) - zephyr_base = get_env_or_bail('ZEPHYR_BASE') - board_dir = get_env_or_bail('BOARD_DIR') - gdb = get_env_or_bail('GDB') - - openocd = os.environ.get('OPENOCD', 'openocd') - extra_init = os.environ.get('OPENOCD_EXTRA_INIT', None) - if extra_init is not None: - extra_init = shlex.split(extra_init) - default_path = os.environ.get('OPENOCD_DEFAULT_PATH', None) - tui = os.environ.get('TUI', None) - tcl_port = int(os.environ.get('TCL_PORT', - str(DEFAULT_ARC_TCL_PORT))) - telnet_port = int(os.environ.get('TELNET_PORT', - str(DEFAULT_ARC_TELNET_PORT))) - gdb_port = int(os.environ.get('GDB_PORT', - str(DEFAULT_ARC_GDB_PORT))) + @classmethod + def create_from_args(cls, args): + if args.gdb is None: + raise ValueError('--gdb not provided at command line') return EmStarterKitBinaryRunner( - elf, zephyr_base, board_dir, - gdb, openocd=openocd, extra_init=extra_init, - default_path=default_path, tui=tui, - tcl_port=tcl_port, telnet_port=telnet_port, - gdb_port=gdb_port, debug=debug) + args.board_dir, args.kernel_elf, args.gdb, + openocd=args.openocd, search=args.openocd_search, + tui=args.tui, tcl_port=args.tcl_port, telnet_port=args.telnet_port, + gdb_port=args.gdb_port, debug=args.verbose) def do_run(self, command, **kwargs): - if command not in {'flash', 'debug', 'debugserver'}: - raise ValueError('{} is not supported'.format(command)) - kwargs['openocd-cfg'] = path.join(self.board_dir, 'support', 'openocd.cfg') @@ -114,7 +82,6 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): server_cmd = (self.openocd_cmd + ['-f', config] + - self.extra_init + ['-c', 'tcl_port {}'.format(self.tcl_port), '-c', 'telnet_port {}'.format(self.telnet_port), '-c', 'gdb_port {}'.format(self.gdb_port), @@ -122,16 +89,11 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): '-c', 'targets', '-c', 'halt']) - tui_arg = [] - if self.tui is not None: - tui_arg = [self.tui] - continue_arg = [] if command == 'flash': continue_arg = ['-ex', 'c'] - gdb_cmd = ([self.gdb] + - tui_arg + + gdb_cmd = (self.gdb_cmd + ['-ex', 'target remote :{}'.format(self.gdb_port), '-ex', 'load'] + continue_arg + diff --git a/scripts/support/runner/bossac.py b/scripts/support/runner/bossac.py index e22b0dceff5..a34be445656 100644 --- a/scripts/support/runner/bossac.py +++ b/scripts/support/runner/bossac.py @@ -4,11 +4,9 @@ '''bossac-specific runner (flash only) for Atmel SAM microcontrollers.''' -from os import path -import os import platform -from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail +from .core import ZephyrBinaryRunner, RunnerCaps DEFAULT_BOSSAC_PORT = '/dev/ttyACM0' @@ -31,25 +29,17 @@ class BossacBinaryRunner(ZephyrBinaryRunner): def capabilities(cls): return RunnerCaps(commands={'flash'}) - def create_from_env(command, debug): - '''Create flasher from environment. + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--bossac', default='bossac', + help='path to bossac, default is bossac') + parser.add_argument('--bossac-port', default='/dev/ttyACM0', + help='serial port to use, default is /dev/ttyACM0') - Required: - - - O: build output directory - - KERNEL_BIN_NAME: name of kernel binary - - Optional: - - - BOSSAC: path to bossac, default is bossac - - BOSSAC_PORT: serial port to use, default is /dev/ttyACM0 - ''' - bin_name = path.join(get_env_or_bail('O'), - get_env_or_bail('KERNEL_BIN_NAME')) - bossac = os.environ.get('BOSSAC', 'bossac') - port = os.environ.get('BOSSAC_PORT', DEFAULT_BOSSAC_PORT) - return BossacBinaryRunner(bin_name, bossac=bossac, port=port, - debug=debug) + @classmethod + def create_from_args(command, args): + return BossacBinaryRunner(args.kernel_bin, bossac=args.bossac, + port=args.bossac_port, debug=args.verbose) def do_run(self, command, **kwargs): if platform.system() != 'Linux': diff --git a/scripts/support/runner/core.py b/scripts/support/runner/core.py index cfb4036ade8..1aafc233cf2 100644 --- a/scripts/support/runner/core.py +++ b/scripts/support/runner/core.py @@ -14,54 +14,9 @@ as well as some other helpers for concrete runner classes. import abc import os import platform -import pprint import shlex import signal import subprocess -import sys - - -def get_env_or_bail(env_var): - '''Get an environment variable, or raise an error. - - In case of KeyError, an error message is printed, along with the - environment, and the exception is re-raised. - ''' - try: - return os.environ[env_var] - except KeyError: - print('Variable {} not in environment:'.format( - env_var), file=sys.stderr) - pprint.pprint(dict(os.environ), stream=sys.stderr) - raise - - -def get_env_bool_or(env_var, default_value): - '''Get an environment variable as a boolean, or return a default value. - - Get an environment variable, interpret it as a base ten - integer, and convert that to a boolean. - - In case the environment variable is not defined, return default_value. - ''' - try: - return bool(int(os.environ[env_var])) - except KeyError: - return default_value - - -def get_env_strip_or(env_var, to_strip, default_value): - '''Get and clean up an environment variable, or return a default value. - - Get the value of env_var from the environment. If it is - defined, return that value with to_strip stripped off. If it - is undefined, return default_value (without any stripping). - ''' - value = os.environ.get(env_var, None) - if value is not None: - return value.strip(to_strip) - else: - return default_value def quote_sh_list(cmd): @@ -227,10 +182,10 @@ class ZephyrBinaryRunner(abc.ABC): binary. This class provides an API for these commands. Every runner has a - name, and declares commands it can handle. Zephyr boards declare - compatible runner(s) by name to the build system, which can then - call into the create_runner() method below to make a concrete - runner instance for use executing a command. + name (like 'pyocd'), and declares commands it can handle (like + 'flash'). Zephyr boards (like 'nrf52_pca10040') declare compatible + runner(s) by name to the build system, which makes concrete runner + instances to execute commands via this class. If your board can use an existing runner, all you have to do is give its name to the build system. How to do that is out of the @@ -240,58 +195,34 @@ class ZephyrBinaryRunner(abc.ABC): If you want to define and use your own runner: 1. Define a ZephyrBinaryRunner subclass, and implement its - abstract methods. Override any methods you need to, especially - capabilities(). + abstract methods. You may need to override capabilities(). 2. Make sure the Python module defining your runner class is - imported by this package's __init__.py (otherwise, - create_runner() won't work). + imported, e.g. by editing this package's __init__.py (otherwise, + get_runners() won't work). 3. Give your runner's name to the Zephyr build system in your board's build files. + For command-line invocation from the Zephyr build system, runners + define their own argparse-based interface through the common + add_parser() (and runner-specific do_add_parser() it delegates + to), and provide a way to create instances of themselves from + parsed arguments via create_from_args(). + Runners use a variety of target-specific tools and configuration values, the user interface to which is abstracted by this class. Each runner subclass should take any values it needs to execute one of these commands in its constructor. The actual - command execution is handled in the run() method. - - At present, the Zephyr build system uses environment variables to - control runner behavior. To support this, a create_runner() - method is defined below. This method takes a runner name, and - iterates over defined ZephyrBinaryRunner subclasses to find the - runner class. It then checks that it supports the command, then - instantiates and returns a runner with configuration determined by - the environment. - - To support this, subclasses currently must define a static method: - create_from_env(). This is called by create_runner() to create a - concrete runner instance. - - The environment-based factories are for legacy use *only*; the - build system is moving away from use of environment variables. The - user must be able to construct and use a runner using only the - constructor and run() method. - - ''' + command execution is handled in the run() method.''' def __init__(self, debug=False): self.debug = debug @staticmethod - def create_runner(runner_name, command, debug): - for cls in ZephyrBinaryRunner.__subclasses__(): - if cls.name() == runner_name: - break - else: - raise ValueError('no runner named {} is known'.format(runner_name)) - - caps = cls.capabilities() - if command not in caps.commands: - raise ValueError('runner {} does not implement command {}'.format( - runner_name, command)) - - return cls.create_from_env(command, debug) + def get_runners(): + '''Get a list of all currently defined runner classes.''' + return ZephyrBinaryRunner.__subclasses__() @classmethod @abc.abstractmethod @@ -314,10 +245,77 @@ class ZephyrBinaryRunner(abc.ABC): Subclasses should override appropriately if needed.''' return RunnerCaps() - @staticmethod + @classmethod + def add_parser(cls, parser): + '''Adds a sub-command parser for this runner. + + The given object, parser, is a sub-command parser from the + argparse module. For more details, refer to the documentation + for argparse.ArgumentParser.add_subparsers(). + + The standard (required) arguments are: + + * --board-dir + * --kernel-elf, --kernel-hex, --kernel-bin + + The standard optional arguments are: + + * --gdb + * --openocd, --openocd-search + + Runner-specific options are added through the do_add_parser() + hook. + + The single positional argument is "command". This is currently + restricted to values 'flash', 'debug', and 'debugserver'.''' + # Required options. + parser.add_argument('--board-dir', required=True, + help='Zephyr board directory') + parser.add_argument('--kernel-elf', required=True, + help='path to kernel binary in .elf format') + parser.add_argument('--kernel-hex', required=True, + help='path to kernel binary in .hex format') + parser.add_argument('--kernel-bin', required=True, + help='path to kernel binary in .bin format') + + # Optional options. + parser.add_argument('--gdb', default=None, + help='GDB compatible with the target') + parser.add_argument('--openocd', default='openocd', + help='OpenOCD to use') + parser.add_argument('--openocd-search', default=None, + help='directory to add to OpenOCD search path') + + # Runner-specific options. + cls.do_add_parser(parser) + + # The lone positional argument. Note that argparse can't cope + # with adding options after the first positional argument, so + # this must come last. + parser.add_argument('command', + choices=['flash', 'debug', 'debugserver'], + help='command to run (flash, debug, debugserver)') + + @classmethod @abc.abstractmethod - def create_from_env(command, debug): - '''Create new runner instance from environment variables.''' + def do_add_parser(cls, parser): + '''Hook for adding runner-specific options. + + Subclasses **must not** add positional arguments. That is, when + calling parser.add_argument(), make sure to begin the argument + with '-' so it is interpreted as an option, rather than a + positional argument. + + * OK: parser.add_argument('--my-option') + * Not OK: parser.add_argument('my-argument').''' + + @classmethod + @abc.abstractmethod + def create_from_args(cls, args): + '''Create an instance from command-line arguments. + + These will have been parsed from the command line according to + the specification defined by add_parser().''' def run(self, command, **kwargs): '''Runs command ('flash', 'debug', 'debugserver'). diff --git a/scripts/support/runner/dfu.py b/scripts/support/runner/dfu.py index a0703ce80b9..e7303d5e8cd 100644 --- a/scripts/support/runner/dfu.py +++ b/scripts/support/runner/dfu.py @@ -4,11 +4,10 @@ '''Runner for flashing with dfu-util.''' -import os import sys import time -from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail +from .core import ZephyrBinaryRunner, RunnerCaps class DfuUtilBinaryRunner(ZephyrBinaryRunner): @@ -33,29 +32,30 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner): def capabilities(cls): return RunnerCaps(commands={'flash'}) - def create_from_env(command, debug): - '''Create flasher from environment. + @classmethod + def do_add_parser(cls, parser): + # Required: + parser.add_argument("--pid", required=True, + help="USB VID:PID of the board") + parser.add_argument("--alt", required=True, + help="interface alternate setting number or name") - Required: + # Optional: + parser.add_argument("--img", + help="binary to flash, default is --kernel-bin") + parser.add_argument("--dfuse-addr", default=None, + help='''target address if the board is a DfuSe + device; ignored it not present''') + parser.add_argument('--dfu-util', default='dfu-util', + help='dfu-util executable; defaults to "dfu-util"') - - DFUUTIL_PID: USB VID:PID of the board - - DFUUTIL_ALT: interface alternate setting number or name - - DFUUTIL_IMG: binary to flash - - Optional: - - - DFUUTIL_DFUSE_ADDR: target address if the board is a - DfuSe device. Ignored if not present. - - DFUUTIL: dfu-util executable, defaults to dfu-util. - ''' - pid = get_env_or_bail('DFUUTIL_PID') - alt = get_env_or_bail('DFUUTIL_ALT') - img = get_env_or_bail('DFUUTIL_IMG') - dfuse = os.environ.get('DFUUTIL_DFUSE_ADDR', None) - exe = os.environ.get('DFUUTIL', 'dfu-util') - - return DfuUtilBinaryRunner(pid, alt, img, dfuse=dfuse, exe=exe, - debug=debug) + @classmethod + def create_from_args(cls, args): + if args.img is None: + args.img = args.kernel_bin + return DfuUtilBinaryRunner(args.pid, args.alt, args.img, + dfuse=args.dfuse_addr, exe=args.dfu_util, + debug=args.verbose) def find_device(self): cmd = list(self.cmd) + ['-l'] diff --git a/scripts/support/runner/esp32.py b/scripts/support/runner/esp32.py index a7836b5a520..868152ef78a 100644 --- a/scripts/support/runner/esp32.py +++ b/scripts/support/runner/esp32.py @@ -5,9 +5,8 @@ '''Runner for flashing ESP32 devices with esptool/espidf.''' from os import path -import os -from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail +from .core import ZephyrBinaryRunner, RunnerCaps class Esp32BinaryRunner(ZephyrBinaryRunner): @@ -33,44 +32,41 @@ class Esp32BinaryRunner(ZephyrBinaryRunner): def capabilities(cls): return RunnerCaps(commands={'flash'}) - def create_from_env(command, debug): - '''Create flasher from environment. + @classmethod + def do_add_parser(cls, parser): + # Required + parser.add_argument('--esp-idf-path', required=True, + help='path to ESP-IDF') - Required: + # Optional + parser.add_argument('--esp-device', default='/dev/ttyUSB0', + help='serial port to flash, default /dev/ttyUSB0') + parser.add_argument('--esp-baud-rate', default='921600', + help='serial baud rate, default 921600') + parser.add_argument('--esp-flash-size', default='detect', + help='flash size, default "detect"') + parser.add_argument('--esp-flash-freq', default='40m', + help='flash frequency, default "40m"') + parser.add_argument('--esp-flash-mode', default='dio', + help='flash mode, default "dio"') + parser.add_argument( + '--esp-tool', + help='''if given, complete path to espidf. default is to search for + it in [ESP_IDF_PATH]/components/esptool_py/esptool/esptool.py''') - - O: build output directory - - KERNEL_ELF_NAME: name of kernel binary in ELF format + @classmethod + def create_from_args(command, args): + if args.esp_tool: + espidf = args.esp_tool + else: + espidf = path.join(args.esp_idf_path, 'components', 'esptool_py', + 'esptool', 'esptool.py') - Optional: - - - ESP_DEVICE: serial port to flash, default /dev/ttyUSB0 - - ESP_BAUD_RATE: serial baud rate, default 921600 - - ESP_FLASH_SIZE: flash size, default 'detect' - - ESP_FLASH_FREQ: flash frequency, default '40m' - - ESP_FLASH_MODE: flash mode, default 'dio' - - ESP_TOOL: complete path to espidf, or set to 'espidf' to look for it - in $ESP_IDF_PATH/components/esptool_py/esptool/esptool.py - ''' - elf = path.join(get_env_or_bail('O'), - get_env_or_bail('KERNEL_ELF_NAME')) - - # TODO add sane device defaults on other platforms than Linux. - device = os.environ.get('ESP_DEVICE', '/dev/ttyUSB0') - baud = os.environ.get('ESP_BAUD_RATE', '921600') - flash_size = os.environ.get('ESP_FLASH_SIZE', 'detect') - flash_freq = os.environ.get('ESP_FLASH_FREQ', '40m') - flash_mode = os.environ.get('ESP_FLASH_MODE', 'dio') - espidf = os.environ.get('ESP_TOOL', 'espidf') - - if espidf == 'espidf': - idf_path = get_env_or_bail('ESP_IDF_PATH') - espidf = path.join(idf_path, 'components', 'esptool_py', 'esptool', - 'esptool.py') - - return Esp32BinaryRunner(elf, device, baud=baud, - flash_size=flash_size, flash_freq=flash_freq, - flash_mode=flash_mode, espidf=espidf, - debug=debug) + return Esp32BinaryRunner( + args.kernel_elf, args.esp_device, baud=args.esp_baud_rate, + flash_size=args.esp_flash_size, flash_freq=args.esp_flash_freq, + flash_mode=args.esp_flash_mode, espidf=espidf, + debug=args.verbose) def do_run(self, command, **kwargs): bin_name = path.splitext(self.elf)[0] + path.extsep + 'bin' diff --git a/scripts/support/runner/jlink.py b/scripts/support/runner/jlink.py index 37a0c449aba..f956955b530 100644 --- a/scripts/support/runner/jlink.py +++ b/scripts/support/runner/jlink.py @@ -4,10 +4,7 @@ '''Runner for debugging with JLink.''' -from os import path -import os - -from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail +from .core import ZephyrBinaryRunner, RunnerCaps DEFAULT_JLINK_GDB_PORT = 2331 @@ -17,7 +14,7 @@ class JLinkBinaryRunner(ZephyrBinaryRunner): def __init__(self, device, gdbserver='JLinkGDBServer', iface='swd', elf_name=None, - gdb=None, gdb_port=DEFAULT_JLINK_GDB_PORT, tui=None, + gdb=None, gdb_port=DEFAULT_JLINK_GDB_PORT, tui=False, debug=False): super(JLinkBinaryRunner, self).__init__(debug=debug) self.device = device @@ -26,7 +23,7 @@ class JLinkBinaryRunner(ZephyrBinaryRunner): self.elf_name = elf_name self.gdb_cmd = [gdb] if gdb is not None else None self.gdb_port = gdb_port - self.tui_arg = [tui] if tui is not None else [] + self.tui_arg = ['-tui'] if tui else [] @classmethod def name(cls): @@ -36,49 +33,28 @@ class JLinkBinaryRunner(ZephyrBinaryRunner): def capabilities(cls): return RunnerCaps(commands={'debug', 'debugserver'}) - def create_from_env(command, debug): - '''Create runner from environment. + @classmethod + def do_add_parser(cls, parser): + # Required: + parser.add_argument('--device', required=True, help='device name') - Required: + # Optional: + parser.add_argument('--iface', default='swd', + help='interface to use, default is swd') + parser.add_argument('--tui', default=False, action='store_true', + help='if given, GDB uses -tui') + parser.add_argument('--gdbserver', default='JLinkGDBServer', + help='GDB server, default is JLinkGDBServer') + parser.add_argument('--gdb-port', default=DEFAULT_JLINK_GDB_PORT, + help='pyocd gdb port, defaults to {}'.format( + DEFAULT_JLINK_GDB_PORT)) - - JLINK_DEVICE: device name - - Required for 'debug': - - - GDB: gdb to use - - O: build output directory - - KERNEL_ELF_NAME: zephyr kernel binary in ELF format - - Optional for 'debug': - - - TUI: if present, passed to gdb server used to flash - - Optional for 'debug', 'debugserver': - - - JLINK_GDBSERVER: default is JLinkGDBServer - - GDB_PORT: default is 2331 - - JLINK_IF: default is swd - ''' - device = get_env_or_bail('JLINK_DEVICE') - - gdb = os.environ.get('GDB', None) - o = os.environ.get('O', None) - elf = os.environ.get('KERNEL_ELF_NAME', None) - elf_name = None - if o is not None: - if elf is not None: - elf_name = path.join(o, elf) - tui = os.environ.get('TUI', None) - - gdbserver = os.environ.get('JLINK_GDBSERVER', 'JLinkGDBServer') - gdb_port = int(os.environ.get('GDB_PORT', - str(DEFAULT_JLINK_GDB_PORT))) - iface = os.environ.get('JLINK_IF', 'swd') - - return JLinkBinaryRunner(device, gdbserver=gdbserver, - iface=iface, elf_name=elf_name, - gdb=gdb, gdb_port=gdb_port, tui=tui, - debug=debug) + @classmethod + def create_from_args(cls, args): + return JLinkBinaryRunner(args.device, gdbserver=args.gdbserver, + iface=args.iface, elf_name=args.kernel_elf, + gdb=args.gdb, gdb_port=args.gdb_port, + tui=args.tui, debug=args.verbose) def print_gdbserver_message(self): print('JLink GDB server running on port {}'.format(self.gdb_port)) diff --git a/scripts/support/runner/nios2.py b/scripts/support/runner/nios2.py index 2916360859e..c172e86252b 100644 --- a/scripts/support/runner/nios2.py +++ b/scripts/support/runner/nios2.py @@ -4,9 +4,6 @@ '''Runner for NIOS II, based on quartus-flash.py and GDB.''' -from os import path -import os - from .core import ZephyrBinaryRunner, NetworkPortHelper @@ -20,61 +17,36 @@ class Nios2BinaryRunner(ZephyrBinaryRunner): # and CONFIG_INCLUDE_RESET_VECTOR must be disabled." def __init__(self, hex_name=None, elf_name=None, cpu_sof=None, - zephyr_base=None, gdb=None, tui=None, debug=False): + quartus_py=None, gdb=None, tui=False, debug=False): super(Nios2BinaryRunner, self).__init__(debug=debug) self.hex_name = hex_name self.elf_name = elf_name self.cpu_sof = cpu_sof - self.zephyr_base = zephyr_base + self.quartus_py = quartus_py self.gdb_cmd = [gdb] if gdb is not None else None - self.tui_arg = [tui] if tui is not None else [] + self.tui_arg = ['-tui'] if tui else [] @classmethod def name(cls): return 'nios2' - def create_from_env(command, debug): - '''Create runner from environment. + @classmethod + def do_add_parser(cls, parser): + # TODO merge quartus-flash.py script into this file. + parser.add_argument('--quartus-flash', required=True) + parser.add_argument('--cpu-sof', required=True, + help='path to the the CPU .sof data') + parser.add_argument('--tui', default=False, action='store_true', + help='if given, GDB uses -tui') - Required for 'flash', 'debug': - - - O: build output directory - - Required for 'flash': - - - KERNEL_HEX_NAME: name of kernel binary in HEX format - - NIOS2_CPU_SOF: location of the CPU .sof data - - ZEPHYR_BASE: zephyr Git repository base directory - - Required for 'debug': - - - KERNEL_ELF_NAME: name of kernel binary in ELF format - - GDB: GDB executable - - Optional for 'debug': - - - TUI: one additional argument to GDB (e.g. -tui) - ''' - cpu_sof = os.environ.get('NIOS2_CPU_SOF', None) - zephyr_base = os.environ.get('ZEPHYR_BASE', None) - - o = os.environ.get('O', None) - hex_ = os.environ.get('KERNEL_HEX_NAME', None) - elf = os.environ.get('KERNEL_ELF_NAME', None) - hex_name = None - elf_name = None - if o is not None: - if hex_ is not None: - hex_name = path.join(o, hex_) - if elf is not None: - elf_name = path.join(o, elf) - - gdb = os.environ.get('GDB', None) - tui = os.environ.get('TUI', None) - - return Nios2BinaryRunner(hex_name=hex_name, elf_name=elf_name, - cpu_sof=cpu_sof, zephyr_base=zephyr_base, - gdb=gdb, tui=tui, debug=debug) + @classmethod + def create_from_args(command, args): + return Nios2BinaryRunner(hex_name=args.kernel_hex, + elf_name=args.kernel_elf, + cpu_sof=args.cpu_sof, + quartus_py=args.quartus_flash, + gdb=args.gdb, tui=args.tui, + debug=args.verbose) def do_run(self, command, **kwargs): if command == 'flash': @@ -83,19 +55,12 @@ class Nios2BinaryRunner(ZephyrBinaryRunner): self.debug_debugserver(command, **kwargs) def flash(self, **kwargs): - sof_msg = ( - 'Cannot flash; ' - 'Please set NIOS2_CPU_SOF variable to location of CPU .sof data') - - if self.zephyr_base is None: - raise ValueError('Cannot flash; ZEPHYR_BASE is missing.') + if self.quartus_py is None: + raise ValueError('Cannot flash; --quartus-flash not given.') if self.cpu_sof is None: - raise ValueError(sof_msg) - if self.hex_name is None: - raise ValueError('Cannot flash; .hex binary name is missing') + raise ValueError('Cannot flash; --cpu-sof not given.') - cmd = [path.join(self.zephyr_base, 'scripts', 'support', - 'quartus-flash.py'), + cmd = [self.quartus_py, '--sof', self.cpu_sof, '--kernel', self.hex_name] diff --git a/scripts/support/runner/nrfjprog.py b/scripts/support/runner/nrfjprog.py index 8b92b33f1f1..7a7c063786d 100644 --- a/scripts/support/runner/nrfjprog.py +++ b/scripts/support/runner/nrfjprog.py @@ -4,10 +4,9 @@ '''Runner for flashing with nrfjprog.''' -from os import path import sys -from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail +from .core import ZephyrBinaryRunner, RunnerCaps class NrfJprogBinaryRunner(ZephyrBinaryRunner): @@ -26,20 +25,16 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner): def capabilities(cls): return RunnerCaps(commands={'flash'}) - def create_from_env(command, debug): - '''Create flasher from environment. + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--nrf-family', required=True, + choices=['NRF51', 'NRF52'], + help='family of nRF MCU') - Required: - - - O: build output directory - - KERNEL_HEX_NAME: name of kernel binary in ELF format - - NRF_FAMILY: e.g. NRF51 or NRF52 - ''' - hex_ = path.join(get_env_or_bail('O'), - get_env_or_bail('KERNEL_HEX_NAME')) - family = get_env_or_bail('NRF_FAMILY') - - return NrfJprogBinaryRunner(hex_, family, debug=debug) + @classmethod + def create_from_args(cls, args): + return NrfJprogBinaryRunner(args.kernel_hex, args.nrf_family, + debug=args.verbose) def get_board_snr_from_user(self): snrs = self.check_output(['nrfjprog', '--ids']) diff --git a/scripts/support/runner/openocd.py b/scripts/support/runner/openocd.py index 85dcaf19468..cd55b16515f 100644 --- a/scripts/support/runner/openocd.py +++ b/scripts/support/runner/openocd.py @@ -5,10 +5,8 @@ '''Runner for openocd.''' from os import path -import os -import shlex -from .core import ZephyrBinaryRunner, get_env_or_bail, get_env_strip_or +from .core import ZephyrBinaryRunner DEFAULT_OPENOCD_TCL_PORT = 6333 DEFAULT_OPENOCD_TELNET_PORT = 4444 @@ -19,10 +17,9 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for openocd.''' def __init__(self, openocd_config, - openocd='openocd', default_path=None, - bin_name=None, elf_name=None, - load_cmd=None, verify_cmd=None, pre_cmd=None, post_cmd=None, - extra_init=None, + openocd='openocd', search=None, + elf_name=None, + pre_cmd=None, load_cmd=None, verify_cmd=None, post_cmd=None, tcl_port=DEFAULT_OPENOCD_TCL_PORT, telnet_port=DEFAULT_OPENOCD_TELNET_PORT, gdb_port=DEFAULT_OPENOCD_GDB_PORT, @@ -31,108 +28,62 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): self.openocd_config = openocd_config search_args = [] - if default_path is not None: - search_args = ['-s', default_path] + if search is not None: + search_args = ['-s', search] self.openocd_cmd = [openocd] + search_args - self.bin_name = bin_name self.elf_name = elf_name self.load_cmd = load_cmd self.verify_cmd = verify_cmd self.pre_cmd = pre_cmd self.post_cmd = post_cmd - self.extra_init = extra_init if extra_init is not None else [] self.tcl_port = tcl_port self.telnet_port = telnet_port self.gdb_port = gdb_port self.gdb_cmd = [gdb] if gdb is not None else None - self.tui_arg = [tui] if tui is not None else [] + self.tui_arg = ['-tui'] if tui else [] @classmethod def name(cls): return 'openocd' - def create_from_env(command, debug): - '''Create runner from environment. + @classmethod + def do_add_parser(cls, parser): + # Options for flashing: + parser.add_argument('--cmd-pre-load', + help='Command to run before flashing') + parser.add_argument('--cmd-load', + help='''Command to load/flash binary + (required when flashing)''') + parser.add_argument('--cmd-verify', + help='''Command to verify flashed binary''') + parser.add_argument('--cmd-post-verify', + help='Command to run after verification') - Required: + # Options for debugging: + parser.add_argument('--tui', default=False, action='store_true', + help='if given, GDB uses -tui') + parser.add_argument('--tcl-port', default=DEFAULT_OPENOCD_TCL_PORT, + help='openocd TCL port, defaults to 6333') + parser.add_argument('--telnet-port', + default=DEFAULT_OPENOCD_TELNET_PORT, + help='openocd telnet port, defaults to 4444') + parser.add_argument('--gdb-port', default=DEFAULT_OPENOCD_GDB_PORT, + help='openocd gdb port, defaults to 3333') - - ZEPHYR_BASE: zephyr Git repository base directory - - BOARD_DIR: directory of board definition + @classmethod + def create_from_args(cls, args): + openocd_config = path.join(args.board_dir, 'support', 'openocd.cfg') - Optional: - - - OPENOCD: path to openocd, defaults to openocd - - OPENOCD_DEFAULT_PATH: openocd search path to use - - Required for 'flash': - - - O: build output directory - - KERNEL_BIN_NAME: zephyr kernel binary - - OPENOCD_LOAD_CMD: command to load binary into flash - - OPENOCD_VERIFY_CMD: command to verify flash executed correctly - - Optional for 'flash': - - - OPENOCD_PRE_CMD: command to run before any others - - OPENOCD_POST_CMD: command to run after verifying flash write - - Required for 'debug': - - - GDB: GDB executable - - O: build output directory - - KERNEL_ELF_NAME: zephyr kernel binary, ELF format - - Optional for 'debug': - - - TUI: one additional argument to GDB (e.g. -tui) - - OPENOCD_EXTRA_INIT: additional arguments to pass to openocd - - TCL_PORT: openocd TCL port, defaults to 6333 - - TELNET_PORT: openocd telnet port, defaults to 4444 - - GDB_PORT: openocd gdb port, defaults to 3333 - ''' - zephyr_base = get_env_or_bail('ZEPHYR_BASE') - board_dir = get_env_or_bail('BOARD_DIR') - openocd_config = path.join(board_dir, 'support', 'openocd.cfg') - - openocd = os.environ.get('OPENOCD', 'openocd') - default_path = os.environ.get('OPENOCD_DEFAULT_PATH', None) - - o = os.environ.get('O', None) - bin_ = os.environ.get('KERNEL_BIN_NAME', None) - elf = os.environ.get('KERNEL_ELF_NAME', None) - bin_name = None - elf_name = None - if o is not None: - if bin_ is not None: - bin_name = path.join(o, bin_) - if elf is not None: - elf_name = path.join(o, elf) - - load_cmd = get_env_strip_or('OPENOCD_LOAD_CMD', '"', None) - verify_cmd = get_env_strip_or('OPENOCD_VERIFY_CMD', '"', None) - pre_cmd = get_env_strip_or('OPENOCD_PRE_CMD', '"', None) - post_cmd = get_env_strip_or('OPENOCD_POST_CMD', '"', None) - - gdb = os.environ.get('GDB', None) - tui = os.environ.get('TUI', None) - extra_init = os.environ.get('OPENOCD_EXTRA_INIT', None) - if extra_init is not None: - extra_init = shlex.split(extra_init) - tcl_port = int(os.environ.get('TCL_PORT', - str(DEFAULT_OPENOCD_TCL_PORT))) - telnet_port = int(os.environ.get('TELNET_PORT', - str(DEFAULT_OPENOCD_TELNET_PORT))) - gdb_port = int(os.environ.get('GDB_PORT', - str(DEFAULT_OPENOCD_GDB_PORT))) - - return OpenOcdBinaryRunner(openocd_config, - openocd=openocd, default_path=default_path, - bin_name=bin_name, elf_name=elf_name, - load_cmd=load_cmd, verify_cmd=verify_cmd, - pre_cmd=pre_cmd, post_cmd=post_cmd, - extra_init=extra_init, tcl_port=tcl_port, - telnet_port=telnet_port, gdb_port=gdb_port, - gdb=gdb, tui=tui, debug=debug) + return OpenOcdBinaryRunner( + openocd_config, + openocd=args.openocd, search=args.openocd_search, + elf_name=args.kernel_elf, + pre_cmd=args.cmd_pre_load, + load_cmd=args.cmd_load, verify_cmd=args.cmd_verify, + post_cmd=args.cmd_post_verify, + tcl_port=args.tcl_port, telnet_port=args.telnet_port, + gdb_port=args.gdb_port, gdb=args.gdb, tui=args.tui, + debug=args.verbose) def do_run(self, command, **kwargs): if command == 'flash': @@ -143,8 +94,6 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): self.do_debugserver(**kwargs) def do_flash(self, **kwargs): - if self.bin_name is None: - raise ValueError('Cannot flash; binary name is missing') if self.load_cmd is None: raise ValueError('Cannot flash; load command is missing') if self.verify_cmd is None: @@ -179,9 +128,8 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): raise ValueError('Cannot debug; no .elf specified') server_cmd = (self.openocd_cmd + - ['-f', self.openocd_config] + - self.extra_init + - ['-c', 'tcl_port {}'.format(self.tcl_port), + ['-f', self.openocd_config, + '-c', 'tcl_port {}'.format(self.tcl_port), '-c', 'telnet_port {}'.format(self.telnet_port), '-c', 'gdb_port {}'.format(self.gdb_port), '-c', 'init', diff --git a/scripts/support/runner/pyocd.py b/scripts/support/runner/pyocd.py index 2e98f1cb4cc..cf17168b0c3 100644 --- a/scripts/support/runner/pyocd.py +++ b/scripts/support/runner/pyocd.py @@ -4,10 +4,10 @@ '''Runner for pyOCD .''' -from os import path import os +import sys -from .core import ZephyrBinaryRunner, get_env_or_bail +from .core import ZephyrBinaryRunner DEFAULT_PYOCD_GDB_PORT = 3333 @@ -17,7 +17,7 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner): def __init__(self, target, flashtool='pyocd-flashtool', gdb=None, gdbserver='pyocd-gdbserver', - gdb_port=DEFAULT_PYOCD_GDB_PORT, tui=None, + gdb_port=DEFAULT_PYOCD_GDB_PORT, tui=False, bin_name=None, elf_name=None, board_id=None, daparg=None, debug=False): super(PyOcdBinaryRunner, self).__init__(debug=debug) @@ -27,7 +27,7 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner): self.gdb_cmd = [gdb] if gdb is not None else None self.gdbserver = gdbserver self.gdb_port = gdb_port - self.tui_args = [tui] if tui is not None else [] + self.tui_args = ['-tui'] if tui else [] self.bin_name = bin_name self.elf_name = elf_name @@ -45,68 +45,47 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner): def name(cls): return 'pyocd' + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--target', required=True, + help='target override') + + parser.add_argument('--daparg', + help='Additional arguments to pyocd tool') + parser.add_argument('--flashtool', default='pyocd-flashtool', + help='flash tool path, default is pyocd-flashtool') + parser.add_argument('--gdbserver', default='pyocd-gdbserver', + help='GDB server, default is pyocd-gdbserver') + parser.add_argument('--gdb-port', default=DEFAULT_PYOCD_GDB_PORT, + help='pyocd gdb port, defaults to {}'.format( + DEFAULT_PYOCD_GDB_PORT)) + parser.add_argument('--tui', default=False, action='store_true', + help='if given, GDB uses -tui') + parser.add_argument('--board-id', + help='ID of board to flash, default is to prompt') + + @classmethod + def create_from_args(cls, args): + daparg = os.environ.get('PYOCD_DAPARG') + if daparg: + print('Warning: setting PYOCD_DAPARG in the environment is', + 'deprecated; use the --daparg option instead.', + file=sys.stderr) + if args.daparg is None: + print('Missing --daparg set to {} from environment'.format( + daparg), + file=sys.stderr) + args.daparg = daparg + + return PyOcdBinaryRunner( + args.target, flashtool=args.flashtool, gdb=args.gdb, + gdbserver=args.gdbserver, gdb_port=args.gdb_port, tui=args.tui, + bin_name=args.kernel_bin, elf_name=args.kernel_elf, + board_id=args.board_id, daparg=args.daparg, debug=args.verbose) + def port_args(self): return ['-p', str(self.gdb_port)] - def create_from_env(command, debug): - '''Create runner from environment. - - Required: - - - PYOCD_TARGET: target override - - Optional: - - - PYOCD_DAPARG: arguments to pass to pyocd tool, default is none - - PYOCD_BOARD_ID: ID of board to flash, default is to prompt - - Required for 'flash': - - - O: build output directory - - KERNEL_BIN_NAME: name of kernel binary - - Optional for 'flash': - - - PYOCD_FLASHTOOL: flash tool path, defaults to pyocd-flashtool - - Required for 'debug': - - - O: build output directory - - KERNEL_ELF_NAME - - GDB: gdb executable - - Optional for 'debug', 'debugserver': - - - TUI: one additional argument to GDB (e.g. -tui) - - GDB_PORT: pyocd gdb port, defaults to 3333 - - PYOCD_GDBSERVER: gdb server executable, defaults to pyocd-gdbserver - ''' - target = get_env_or_bail('PYOCD_TARGET') - - o = os.environ.get('O', None) - bin_ = os.environ.get('KERNEL_BIN_NAME', None) - elf = os.environ.get('KERNEL_ELF_NAME', None) - bin_name = None - elf_name = None - if o is not None: - if bin_ is not None: - bin_name = path.join(o, bin_) - if elf is not None: - elf_name = path.join(o, elf) - - flashtool = os.environ.get('PYOCD_FLASHTOOL', 'pyocd-flashtool') - board_id = os.environ.get('PYOCD_BOARD_ID', None) - daparg = os.environ.get('PYOCD_DAPARG', None) - gdb = os.environ.get('GDB', None) - gdbserver = os.environ.get('PYOCD_GDBSERVER', 'pyocd-gdbserver') - gdb_port = os.environ.get('GDB_PORT', DEFAULT_PYOCD_GDB_PORT) - tui = os.environ.get('TUI', None) - - return PyOcdBinaryRunner(target, flashtool=flashtool, gdb=gdb, - gdbserver=gdbserver, gdb_port=gdb_port, - tui=tui, bin_name=bin_name, elf_name=elf_name, - board_id=board_id, daparg=daparg, debug=debug) - def do_run(self, command, **kwargs): if command == 'flash': self.flash(**kwargs) diff --git a/scripts/support/runner/qemu.py b/scripts/support/runner/qemu.py index 8bea47ec4e5..4ad79daca03 100644 --- a/scripts/support/runner/qemu.py +++ b/scripts/support/runner/qemu.py @@ -17,9 +17,13 @@ class QemuBinaryRunner(ZephyrBinaryRunner): def name(cls): return 'qemu' - def create_from_env(command, debug): - '''Create runner. No environment dependencies.''' - return QemuBinaryRunner() + @classmethod + def do_add_parser(cls, parser): + pass # Nothing to do. + + @classmethod + def create_from_args(command, args): + return QemuBinaryRunner(debug=args.verbose) def do_run(self, command, **kwargs): if command == 'debugserver': diff --git a/scripts/support/runner/xtensa.py b/scripts/support/runner/xtensa.py index 3098e6b195a..ad0897ed223 100644 --- a/scripts/support/runner/xtensa.py +++ b/scripts/support/runner/xtensa.py @@ -6,7 +6,7 @@ from os import path -from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail +from .core import ZephyrBinaryRunner, RunnerCaps class XtensaBinaryRunner(ZephyrBinaryRunner): @@ -25,20 +25,15 @@ class XtensaBinaryRunner(ZephyrBinaryRunner): def capabilities(cls): return RunnerCaps(commands={'debug'}) - def create_from_env(command, debug): - '''Create runner from environment. + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--xcc-tools', required=True, + help='path to XTensa tools') - Required: - - - XCC_TOOLS: path to Xtensa tools - - O: build output directory - - KERNEL_ELF_NAME: zephyr kernel binary in ELF format - ''' - xt_gdb = path.join(get_env_or_bail('XCC_TOOLS'), 'bin', 'xt-gdb') - elf_name = path.join(get_env_or_bail('O'), - get_env_or_bail('KERNEL_ELF_NAME')) - - return XtensaBinaryRunner(xt_gdb, elf_name) + @classmethod + def create_from_args(command, args): + xt_gdb = path.join(args.xcc_tools, 'bin', 'xt-gdb') + return XtensaBinaryRunner(xt_gdb, args.kernel_elf, args.verbose) def do_run(self, command, **kwargs): gdb_cmd = (self.gdb_cmd + [self.elf_name]) diff --git a/scripts/support/zephyr_flash_debug.py b/scripts/support/zephyr_flash_debug.py index a600465487d..12acea2a879 100755 --- a/scripts/support/zephyr_flash_debug.py +++ b/scripts/support/zephyr_flash_debug.py @@ -14,45 +14,68 @@ supported by Zephyr, as well as backend-specific scripts for tools such as OpenOCD, pyOCD, etc. """ +import argparse +import functools import sys -from runner.core import ZephyrBinaryRunner, get_env_bool_or +from runner.core import ZephyrBinaryRunner -# TODO: Stop using environment variables. -# -# Migrate the build system so we can use an argparse.ArgumentParser and -# per-flasher subparsers, so invoking the script becomes something like: -# -# python zephyr_flash_debug.py openocd --openocd-bin=/openocd/path ... -# -# For now, maintain compatibility. -def run(runner_name, command, debug): +def runner_handler(cls, args): + runner = cls.create_from_args(args) + # This relies on ZephyrBinaryRunner.add_parser() having command as + # its single positional argument; see its docstring for details. + runner.run(args.command) + + +def main(): + # Argument handling is split into a two-level structure, with + # common options to the script first, then a sub-command (i.e. a + # runner name), then options and arguments for that sub-command + # (like 'flash --some-option=value'). + # + # For top-level help (including a list of runners), run: + # + # $ZEPHYR_BASE/.../SCRIPT.py -h + # + # For help on a particular RUNNER (like 'pyocd'), run: + # + # $ZEPHYR_BASE/.../SCRIPT.py RUNNER -h + # + # For verbose output, use: + # + # $ZEPHYR_BASE/.../SCRIPT.py [-v|--verbose] RUNNER [--runner-options] + # + # Note that --verbose comes *before* RUNNER, not after! + top_parser = argparse.ArgumentParser() + top_parser.add_argument('-v', '--verbose', + default=False, action='store_true', + help='If set, enable verbose output.') + sub_parsers = top_parser.add_subparsers(dest='runner') + + # Add a sub-command for each runner. (It's a bit hackish for runners + # to know about argparse, but it's good enough for now.) + handlers = {} + for cls in ZephyrBinaryRunner.get_runners(): + if cls.name() in handlers: + print('Runner {} name is already a sub-command'.format(cls.name()), + file=sys.sterr) + sys.exit(1) + sub_parser = sub_parsers.add_parser(cls.name()) + cls.add_parser(sub_parser) + handlers[cls.name()] = functools.partial(runner_handler, cls) + + args = top_parser.parse_args() + if args.runner is None: + runners = ', '.join(handlers.keys()) + print('Missing runner; choices: {}'.format(runners), file=sys.stderr) + sys.exit(1) try: - runner = ZephyrBinaryRunner.create_runner(runner_name, command, debug) - except ValueError: - print('runner {} is not available or does not support {}'.format( - runner_name, command), - file=sys.stderr) + handlers[args.runner](args) + except Exception as e: + print('Error: {}'.format(e), file=sys.stderr) raise - runner.run(command) - if __name__ == '__main__': - commands = {'flash', 'debug', 'debugserver'} - debug = True - try: - debug = get_env_bool_or('VERBOSE', False) - if len(sys.argv) != 3 or sys.argv[2] not in commands: - raise ValueError('usage: {} <{}>'.format( - sys.argv[0], '|'.join(commands))) - run(sys.argv[1], sys.argv[2], debug) - except Exception as e: - if debug: - raise - else: - print('Error: {}'.format(e), file=sys.stderr) - print('Re-run with VERBOSE=1 for a stack trace.', - file=sys.stderr) - sys.exit(1) + main()