diff --git a/components/esptool_py/project_include.cmake b/components/esptool_py/project_include.cmake index aee2275802..9f051b2359 100644 --- a/components/esptool_py/project_include.cmake +++ b/components/esptool_py/project_include.cmake @@ -12,7 +12,6 @@ set(ESPTOOLPY ${python} "$ENV{ESPTOOL_WRAPPER}" "${CMAKE_CURRENT_LIST_DIR}/espto set(ESPSECUREPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py") set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py") set(ESPMONITOR ${python} -m esp_idf_monitor) -set(ESPMKUF2 ${python} "${idf_path}/tools/mkuf2.py" write --chip ${chip_model}) set(ESPTOOLPY_CHIP "${chip_model}") if(NOT CONFIG_APP_BUILD_TYPE_RAM AND CONFIG_APP_BUILD_GENERATE_BINARIES) @@ -197,30 +196,6 @@ add_custom_target(erase_flash VERBATIM ) -set(UF2_ARGS --json "${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json") - -add_custom_target(uf2 - COMMAND ${CMAKE_COMMAND} - -D "IDF_PATH=${idf_path}" - -D "SERIAL_TOOL=${ESPMKUF2}" - -D "SERIAL_TOOL_ARGS=${UF2_ARGS};-o;${CMAKE_CURRENT_BINARY_DIR}/uf2.bin" - -P run_serial_tool.cmake - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - USES_TERMINAL - VERBATIM - ) - -add_custom_target(uf2-app - COMMAND ${CMAKE_COMMAND} - -D "IDF_PATH=${idf_path}" - -D "SERIAL_TOOL=${ESPMKUF2}" - -D "SERIAL_TOOL_ARGS=${UF2_ARGS};-o;${CMAKE_CURRENT_BINARY_DIR}/uf2-app.bin;--bin;app" - -P run_serial_tool.cmake - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - USES_TERMINAL - VERBATIM - ) - set(MERGE_BIN_ARGS merge_bin) if(DEFINED ENV{ESP_MERGE_BIN_OUTPUT}) list(APPEND MERGE_BIN_ARGS "-o" "$ENV{ESP_MERGE_BIN_OUTPUT}") diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index b59423bb36..7527f19bd7 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -884,6 +884,33 @@ macro(project project_name) # Add DFU build and flash targets __add_dfu_targets() + # Add uf2 related targets + idf_build_get_property(idf_path IDF_PATH) + idf_build_get_property(python PYTHON) + + set(UF2_ARGS --json "${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json") + set(UF2_CMD ${python} "${idf_path}/tools/mkuf2.py" write --chip ${chip_model}) + + add_custom_target(uf2 + COMMAND ${CMAKE_COMMAND} + -D "IDF_PATH=${idf_path}" + -D "UF2_CMD=${UF2_CMD}" + -D "UF2_ARGS=${UF2_ARGS};-o;${CMAKE_CURRENT_BINARY_DIR}/uf2.bin" + -P "${idf_path}/tools/cmake/run_uf2_cmds.cmake" + USES_TERMINAL + VERBATIM + ) + + add_custom_target(uf2-app + COMMAND ${CMAKE_COMMAND} + -D "IDF_PATH=${idf_path}" + -D "UF2_CMD=${UF2_CMD}" + -D "UF2_ARGS=${UF2_ARGS};-o;${CMAKE_CURRENT_BINARY_DIR}/uf2-app.bin;--bin;app" + -P "${idf_path}/tools/cmake/run_uf2_cmds.cmake" + USES_TERMINAL + VERBATIM + ) + idf_build_executable(${project_elf}) __project_info("${test_components}") diff --git a/tools/cmake/run_uf2_cmds.cmake b/tools/cmake/run_uf2_cmds.cmake new file mode 100644 index 0000000000..1ed4d5c0fc --- /dev/null +++ b/tools/cmake/run_uf2_cmds.cmake @@ -0,0 +1,27 @@ +# A CMake script to run dfu-util from within ninja or make +# or another cmake-based build runner +# +# It is recommended to NOT USE this CMake script directly + +cmake_minimum_required(VERSION 3.16) + +set(UF2_CMD "${UF2_CMD}") +set(UF2_ARGS "${UF2_ARGS}") + +if(NOT UF2_CMD) + message(FATAL_ERROR "UF2_CMD must be specified on the CMake command line.") +endif() + +if(NOT UF2_ARGS) + message(FATAL_ERROR "UF2_ARGS must be specified on the CMake command line.") +endif() + +set(uf2_cmd_with_args ${UF2_CMD}) +list(APPEND uf2_cmd_with_args ${UF2_ARGS}) + +execute_process(COMMAND ${uf2_cmd_with_args} + RESULT_VARIABLE result) + +if(${result}) + message(FATAL_ERROR "${UF2_CMD} failed") +endif() diff --git a/tools/test_idf_py/test_idf_py.py b/tools/test_idf_py/test_idf_py.py index 9ccdfe0924..9daac230c3 100755 --- a/tools/test_idf_py/test_idf_py.py +++ b/tools/test_idf_py/test_idf_py.py @@ -549,5 +549,38 @@ class TestMergeBinCommands(TestWrapperCommands): self.assertIn(f'Merged binary {merged_binary_name} will be created in the build directory...', output) +class TestUF2Commands(TestWrapperCommands): + """ + Test if uf2 commands are invoked as expected. + This test is not testing the functionality of mkuf2.py/idf.py uf2, but the invocation of the command from idf.py. + """ + + def test_uf2(self): + uf2_command = [sys.executable, idf_py_path, 'uf2'] + output = self.call_command(uf2_command) + self.assertIn('Executing:', output) + + def test_uf2_with_envvars(self): + # Values do not really matter, they should not be used. + os.environ['ESPBAUD'] = '115200' + os.environ['ESPPORT'] = '/dev/ttyUSB0' + self.test_uf2() + os.environ.pop('ESPBAUD') + os.environ.pop('ESPPORT') + + def test_uf2_app(self): + uf2_app_command = [sys.executable, idf_py_path, 'uf2-app'] + output = self.call_command(uf2_app_command) + self.assertIn('Executing:', output) + + def test_uf2_app_with_envvars(self): + # Values do not really matter, they should not be used. + os.environ['ESPBAUD'] = '115200' + os.environ['ESPPORT'] = '/dev/ttyUSB0' + self.test_uf2_app() + os.environ.pop('ESPBAUD') + os.environ.pop('ESPPORT') + + if __name__ == '__main__': main()