diff --git a/components/esptool_py/project_include.cmake b/components/esptool_py/project_include.cmake index 53f42e6398..48750a929f 100644 --- a/components/esptool_py/project_include.cmake +++ b/components/esptool_py/project_include.cmake @@ -173,6 +173,11 @@ esptool_py_custom_target(app-flash app "app") if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT) esptool_py_custom_target(encrypted-flash encrypted_project "app;partition_table;bootloader") esptool_py_custom_target(encrypted-app-flash encrypted_app "app") +else() + fail_target(encrypted-flash "Error: The target encrypted-flash requires" + "CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT to be enabled.") + fail_target(encrypted-app-flash "Error: The target encrypted-app-flash requires" + "CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT to be enabled.") endif() # esptool_py_flash_project_args diff --git a/components/partition_table/CMakeLists.txt b/components/partition_table/CMakeLists.txt index 5faf551910..20f6a7d6ea 100644 --- a/components/partition_table/CMakeLists.txt +++ b/components/partition_table/CMakeLists.txt @@ -33,15 +33,24 @@ endif() idf_build_get_property(build_dir BUILD_DIR) idf_build_get_property(python PYTHON) +set(gen_partition_table "${python}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py" "-q" + "--offset" "${PARTITION_TABLE_OFFSET}" "${md5_opt}" "${flashsize_opt}" + "${partition_secure_opt}" ) + add_custom_command(OUTPUT "${build_dir}/partition_table/${unsigned_partition_bin}" - COMMAND "${python}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py" - -q --offset ${PARTITION_TABLE_OFFSET} ${md5_opt} ${flashsize_opt} - ${partition_secure_opt} ${partition_csv} ${build_dir}/partition_table/${unsigned_partition_bin} + COMMAND ${gen_partition_table} "${partition_csv}" "${build_dir}/partition_table/${unsigned_partition_bin}" DEPENDS ${partition_csv} "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py" VERBATIM) if(EXISTS ${partition_csv}) - add_custom_target(partition_table ALL DEPENDS "${build_dir}/partition_table/${final_partition_bin}") + add_custom_target(partition_table ALL + DEPENDS "${build_dir}/partition_table/${unsigned_partition_bin}" + "${build_dir}/partition_table/${final_partition_bin}" + COMMAND ${CMAKE_COMMAND} -E echo "Partition table binary generated. Contents:" + COMMAND ${CMAKE_COMMAND} -E echo "*******************************************************************************" + COMMAND ${gen_partition_table} "${build_dir}/partition_table/${unsigned_partition_bin}" + COMMAND ${CMAKE_COMMAND} -E echo "*******************************************************************************" + VERBATIM) else() # If the partition input CSV is not found, create a phony partition_table target that # fails the build. fail_at_build_time also touches CMakeCache.txt to cause a cmake run next time @@ -68,7 +77,7 @@ if(CONFIG_SECURE_SIGNED_APPS) add_custom_command(TARGET partition_table POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Partition table built but not signed. Sign partition data before flashing:" - COMMAND ${CMAKE_COMMAND} -E echo + COMMAND ${CMAKE_COMMAND} -E echo "\t${espsecurepy} sign_data --keyfile KEYFILE ${build_dir}/partition_table/${final_partition_bin}" VERBATIM) endif() diff --git a/components/ulp/component_ulp_common.cmake b/components/ulp/component_ulp_common.cmake index ce207f802f..30cbe44a72 100644 --- a/components/ulp/component_ulp_common.cmake +++ b/components/ulp/component_ulp_common.cmake @@ -15,4 +15,4 @@ foreach(ulp_exp_dep_src ${ULP_EXP_DEP_SRCS}) list(APPEND ulp_dep_srcs ${ulp_dep_src}) endforeach() -ulp_embed_binary(${ULP_APP_NAME} ${ulp_srcs} ${ulp_dep_srcs}) +ulp_embed_binary(${ULP_APP_NAME} "${ulp_srcs}" "${ulp_dep_srcs}") diff --git a/components/ulp/project_include.cmake b/components/ulp/project_include.cmake index e33ea2d503..56ee3ac10b 100644 --- a/components/ulp/project_include.cmake +++ b/components/ulp/project_include.cmake @@ -40,10 +40,9 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs) INSTALL_COMMAND "" CMAKE_ARGS -DCMAKE_GENERATOR=${CMAKE_GENERATOR} -DCMAKE_TOOLCHAIN_FILE=${idf_path}/components/ulp/cmake/toolchain-ulp.cmake - -DULP_S_SOURCES=${sources} -DULP_APP_NAME=${app_name} + -DULP_S_SOURCES=$ + -DULP_APP_NAME=${app_name} -DCOMPONENT_DIR=${COMPONENT_DIR} - # Even though this resolves to a ';' separated list, this is fine. This must be special behavior - # for generator expressions. -DCOMPONENT_INCLUDES=$ -DIDF_PATH=${idf_path} -DSDKCONFIG=${SDKCONFIG_HEADER} @@ -53,9 +52,10 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs) BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name} BUILD_ALWAYS 1 - LIST_SEPARATOR | ) + set_property(TARGET ${app_name} PROPERTY ULP_SOURCES "${sources}") + spaces2list(exp_dep_srcs) set_source_files_properties(${exp_dep_srcs} PROPERTIES OBJECT_DEPENDS ${ulp_artifacts}) diff --git a/components/ulp/test/CMakeLists.txt b/components/ulp/test/CMakeLists.txt index 27311f9530..072cfeb867 100644 --- a/components/ulp/test/CMakeLists.txt +++ b/components/ulp/test/CMakeLists.txt @@ -5,4 +5,4 @@ idf_component_register(SRC_DIRS "." set(ulp_app_name ulp_test_app) set(ulp_s_sources "ulp/test_jumps.S") set(ulp_exp_dep_srcs "test_ulp_as.c") -ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) +ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") diff --git a/docs/en/api-guides/ulp.rst b/docs/en/api-guides/ulp.rst index 8cc9761f55..e68b102062 100644 --- a/docs/en/api-guides/ulp.rst +++ b/docs/en/api-guides/ulp.rst @@ -39,7 +39,7 @@ To compile ULP code as part of a component, the following steps must be taken: set(ulp_s_sources ulp/ulp_assembly_source_file.S) set(ulp_exp_dep_srcs "ulp_c_source_file.c") - ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) + ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here will also be used other generated artifacts such as the ELF file, map file, header file and linker export file. The second argument specifies the ULP assembly source files. diff --git a/docs/zh_CN/api-guides/ulp.rst b/docs/zh_CN/api-guides/ulp.rst index 13ed09045c..b4e122d65a 100644 --- a/docs/zh_CN/api-guides/ulp.rst +++ b/docs/zh_CN/api-guides/ulp.rst @@ -44,8 +44,7 @@ ULP 协处理器代码是用汇编语言编写的,并使用 `binutils-esp32ulp ``set(ULP_APP_NAME ulp_${COMPONENT_NAME})`` 为生成的 ULP 应用程序设置名称,不带扩展名。此名称用于 ULP 应用程序的构建输出:ELF 文件、.map 文件、二进制文件、生成的头文件和链接器导出文件。 -``set(ULP_S_SOURCES "ulp/ulp_assembly_source_file_1.S ulp/ulp_assembly_source_file_2.S")`` - 设置要传递给 ULP 汇编器的程序集文件列表,用空格隔开,路径可以是绝对路径,也可以是组件 CMakeLists.txt 的相对路径。 + ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") ``set(ULP_EXP_DEP_SRCS "ulp_c_source_file_1.c ulp_c_source_file_2.c")`` 设置组件中源文件名称的列表。所有包含被生成的头文件的原文件都必须在列表里。此列表建立正确构建依赖项,并确保在构建过程会先生成才编译包含头文件的原文件。请参考下文,查看为 ULP 应用程序生成的头文件等相关概念。此列表需要用空格隔开,路径可以是组件 CMakeLists.txt 文件的相对路径,也可以是绝对路径。 diff --git a/examples/system/ulp/README.md b/examples/system/ulp/README.md index 4b2c5341a1..f46f3f7152 100644 --- a/examples/system/ulp/README.md +++ b/examples/system/ulp/README.md @@ -2,7 +2,7 @@ This example demonstrates how to program the ULP coprocessor to count pulses on an IO while the main CPUs are either running some other code or are in deep sleep. See the README.md file in the upper level 'examples' directory for more information about examples. -ULP program written in assembly can be found in `ulp/pulse_cnt.S`. The build system assembles and links this program, converts it into binary format, and embeds it into the .rodata section of the ESP-IDF application. +ULP program written in assembly can be found across `ulp/pulse_cnt.S` and `ulp/wake_up.S` (demonstrating multiple ULP source files). The build system assembles and links this program, converts it into binary format, and embeds it into the .rodata section of the ESP-IDF application. At runtime, the main code running on the ESP32 (found in main.c) loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_load_binary` function. Main code configures the ULP program by setting up values of some variables and then starts it using `ulp_run`. Once the ULP program is started, it runs periodically, with the period set by the main program. The main program enables ULP wakeup source and puts the chip into deep sleep mode. diff --git a/examples/system/ulp/main/CMakeLists.txt b/examples/system/ulp/main/CMakeLists.txt index af7cb3f765..1ac5db2578 100644 --- a/examples/system/ulp/main/CMakeLists.txt +++ b/examples/system/ulp/main/CMakeLists.txt @@ -10,7 +10,7 @@ set(ulp_app_name ulp_${COMPONENT_NAME}) # 2. Specify all assembly source files. # Files should be placed into a separate directory (in this case, ulp/), # which should not be added to COMPONENT_SRCS. -set(ulp_s_sources "ulp/pulse_cnt.S") +set(ulp_s_sources "ulp/pulse_cnt.S" "ulp/wake_up.S") # # 3. List all the component source files which include automatically # generated ULP export file, ${ulp_app_name}.h: @@ -18,4 +18,4 @@ set(ulp_exp_dep_srcs "ulp_example_main.c") # # 4. Call function to build ULP binary and embed in project using the argument # values above. -ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) +ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") diff --git a/examples/system/ulp/main/component.mk b/examples/system/ulp/main/component.mk index 566757a56b..55c5ba352b 100644 --- a/examples/system/ulp/main/component.mk +++ b/examples/system/ulp/main/component.mk @@ -11,7 +11,7 @@ ULP_APP_NAME ?= ulp_$(COMPONENT_NAME) # Files should be placed into a separate directory (in this case, ulp/), # which should not be added to COMPONENT_SRCDIRS. ULP_S_SOURCES = $(addprefix $(COMPONENT_PATH)/ulp/, \ - pulse_cnt.S \ + pulse_cnt.S wake_up.S\ ) # # 3. List all the component object files which include automatically diff --git a/examples/system/ulp/main/ulp/pulse_cnt.S b/examples/system/ulp/main/ulp/pulse_cnt.S index 774375e2a1..33e6ef6867 100644 --- a/examples/system/ulp/main/ulp/pulse_cnt.S +++ b/examples/system/ulp/main/ulp/pulse_cnt.S @@ -144,14 +144,3 @@ edge_detected: jump wake_up, eq /* Not yet. End program */ halt - - .global wake_up -wake_up: - /* Check if the system can be woken up */ - READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP) - and r0, r0, 1 - jump wake_up, eq - - /* Wake up the SoC, end program */ - wake - halt diff --git a/examples/system/ulp/main/ulp/wake_up.S b/examples/system/ulp/main/ulp/wake_up.S new file mode 100644 index 0000000000..ec2e05da4e --- /dev/null +++ b/examples/system/ulp/main/ulp/wake_up.S @@ -0,0 +1,16 @@ +/* ULP assembly files are passed through C preprocessor first, so include directives + and C macros may be used in these files + */ +#include "soc/rtc_cntl_reg.h" +#include "soc/soc_ulp.h" + + .global wake_up +wake_up: + /* Check if the system can be woken up */ + READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP) + and r0, r0, 1 + jump wake_up, eq + + /* Wake up the SoC, end program */ + wake + halt diff --git a/examples/system/ulp_adc/main/CMakeLists.txt b/examples/system/ulp_adc/main/CMakeLists.txt index ef85f9b2fd..c2da076199 100644 --- a/examples/system/ulp_adc/main/CMakeLists.txt +++ b/examples/system/ulp_adc/main/CMakeLists.txt @@ -18,4 +18,4 @@ set(ulp_exp_dep_srcs "ulp_adc_example_main.c") # # 4. Call function to build ULP binary and embed in project using the argument # values above. -ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) +ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index 974b6281f7..ea88b479a9 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -395,6 +395,10 @@ function run_tests() (grep '"command"' build/compile_commands.json | grep -v mfix-esp32-psram-cache-issue) && failure "All commands in compile_commands.json should use PSRAM cache workaround" rm -r build + print_status "Displays partition table when executing target partition_table" + idf.py partition_table | grep -E "# Espressif .+ Partition Table" + rm -r build + print_status "Make sure a full build never runs '/usr/bin/env python' or similar" OLDPATH="$PATH" PYTHON="$(which python)" diff --git a/tools/cmake/scripts/fail.cmake b/tools/cmake/scripts/fail.cmake index 5ceddb3ca6..b33aec4c36 100644 --- a/tools/cmake/scripts/fail.cmake +++ b/tools/cmake/scripts/fail.cmake @@ -1,4 +1,4 @@ # 'cmake -E' doesn't have a way to fail outright, so run this script # with 'cmake -P' to fail a build. -message(FATAL_ERROR "Failing the build (see errors on lines above)") +message(FATAL_ERROR "$ENV{FAIL_MESSAGE}") diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index 5d3a8ebc69..6cd1a5cd07 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -214,13 +214,37 @@ function(fail_at_build_time target_name message_line0) set(filename "${CMAKE_CURRENT_BINARY_DIR}/${filename}.cmake") file(WRITE "${filename}" "") include("${filename}") + set(fail_message "Failing the build (see errors on lines above)") add_custom_target(${target_name} ALL ${message_lines} COMMAND ${CMAKE_COMMAND} -E remove "${filename}" - COMMAND ${CMAKE_COMMAND} -P ${idf_path}/tools/cmake/scripts/fail.cmake + COMMAND ${CMAKE_COMMAND} -E env FAIL_MESSAGE=${fail_message} + ${CMAKE_COMMAND} -P ${idf_path}/tools/cmake/scripts/fail.cmake VERBATIM) endfunction() +# fail_target +# +# Creates a phony target which fails when invoked. This is used when the necessary conditions +# for a target are not met, such as configuration. Rather than ommitting the target altogether, +# we fail execution with a helpful message. +function(fail_target target_name message_line0) + idf_build_get_property(idf_path IDF_PATH) + set(message_lines COMMAND ${CMAKE_COMMAND} -E echo "${message_line0}") + foreach(message_line ${ARGN}) + set(message_lines ${message_lines} COMMAND ${CMAKE_COMMAND} -E echo "${message_line}") + endforeach() + # Generate a timestamp file that gets included. When deleted on build, this forces CMake + # to rerun. + set(fail_message "Failed executing target (see errors on lines above)") + add_custom_target(${target_name} + ${message_lines} + COMMAND ${CMAKE_COMMAND} -E env FAIL_MESSAGE=${fail_message} + ${CMAKE_COMMAND} -P ${idf_path}/tools/cmake/scripts/fail.cmake + VERBATIM) +endfunction() + + function(check_exclusive_args args prefix) set(_args ${args}) spaces2list(_args)