Merge branch 'feature/use_cmake_function_call_for_embedding_ulp' into 'master'

Use function call for embedding ULP binaries

See merge request idf/esp-idf!4242
This commit is contained in:
Angus Gratton 2019-05-27 13:14:09 +08:00
commit 02f2e63662
6 changed files with 117 additions and 105 deletions

View File

@ -1,63 +1,18 @@
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
spaces2list(ULP_S_SOURCES)
foreach(ulp_s_source ${ULP_S_SOURCES})
get_filename_component(ulp_s_source ${ulp_s_source} ABSOLUTE)
list(APPEND ulp_s_sources ${ulp_s_source})
endforeach()
message(WARNING "Embedding ULP binary by including \
${IDF_PATH}/components/ulp/component_ulp_common.cmake is deprecated. Use `ulp_embed_binary` instead. \
See API Guide for more details.")
foreach(ulp_s_source ${ulp_s_sources})
get_filename_component(ulp_ps_source ${ulp_s_source} NAME_WE)
set(ulp_ps_output ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ulp_ps_source}.ulp.S)
list(APPEND ulp_ps_sources ${ulp_ps_output})
endforeach()
spaces2list(ULP_S_SOURCES)
spaces2list(ULP_EXP_DEP_SRCS)
set(ulp_artifacts_prefix ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME})
foreach(ulp_s_source ${ULP_S_SOURCES})
get_filename_component(ulp_src ${ulp_s_source} ABSOLUTE BASE_DIR ${COMPONENT_DIR})
list(APPEND ulp_srcs ${ulp_src})
endforeach()
set(ulp_artifacts ${ulp_artifacts_prefix}.bin
${ulp_artifacts_prefix}.ld
${ulp_artifacts_prefix}.h)
foreach(ulp_exp_dep_src ${ULP_EXP_DEP_SRCS})
get_filename_component(ulp_dep_src ${ulp_exp_dep_src} ABSOLUTE BASE_DIR ${COMPONENT_DIR})
list(APPEND ulp_dep_srcs ${ulp_dep_src})
endforeach()
set(ulp_artifacts_extras ${ulp_artifacts_prefix}.map
${ulp_artifacts_prefix}.sym
${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/esp32.ulp.ld)
# Replace the separator for the list of ULP source files that will be passed to
# the external ULP project. This is a workaround to the bug https://public.kitware.com/Bug/view.php?id=16137.
string(REPLACE ";" "|" ulp_s_sources "${ulp_s_sources}")
idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER)
idf_build_get_property(idf_path IDF_PATH)
idf_build_get_property(python PYTHON)
externalproject_add(${ULP_APP_NAME}
SOURCE_DIR ${idf_path}/components/ulp/cmake
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}
INSTALL_COMMAND ""
CMAKE_ARGS -DCMAKE_GENERATOR=${CMAKE_GENERATOR}
-DCMAKE_TOOLCHAIN_FILE=${idf_path}/components/ulp/cmake/toolchain-ulp.cmake
-DULP_S_SOURCES=${ulp_s_sources} -DULP_APP_NAME=${ULP_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=$<TARGET_PROPERTY:${COMPONENT_LIB},INTERFACE_INCLUDE_DIRECTORIES>
-DIDF_PATH=${idf_path}
-DSDKCONFIG=${sdkconfig_header}
-DPYTHON=${python}
BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME} --target build
BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources}
${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME}
BUILD_ALWAYS 1
LIST_SEPARATOR |
)
spaces2list(ULP_EXP_DEP_SRCS)
set_source_files_properties(${ULP_EXP_DEP_SRCS} PROPERTIES OBJECT_DEPENDS ${ulp_artifacts})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME})
add_custom_target(${ULP_APP_NAME}_artifacts DEPENDS ${ULP_APP_NAME})
add_dependencies(${COMPONENT_LIB} ${ULP_APP_NAME}_artifacts)
target_linker_script(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME}.ld)
target_add_binary_data(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME}.bin BINARY)
endif()
ulp_embed_binary(${ULP_APP_NAME} ${ulp_srcs} ${ulp_dep_srcs})

View File

@ -0,0 +1,67 @@
# ulp_embed_binary
#
# Create ULP binary and embed into the application.
function(ulp_embed_binary app_name s_sources exp_dep_srcs)
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
spaces2list(s_sources)
foreach(source ${s_sources})
get_filename_component(source ${source} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_LIST_DIR})
list(APPEND sources ${source})
endforeach()
foreach(source ${sources})
get_filename_component(ps_source ${source} NAME_WE)
set(ps_output ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${ps_source}.ulp.S)
list(APPEND ps_sources ${ps_output})
endforeach()
set(ulp_artifacts_prefix ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name})
set(ulp_artifacts ${ulp_artifacts_prefix}.bin
${ulp_artifacts_prefix}.ld
${ulp_artifacts_prefix}.h)
set(ulp_artifacts_extras ${ulp_artifacts_prefix}.map
${ulp_artifacts_prefix}.sym
${CMAKE_CURRENT_BINARY_DIR}/${app_name}/esp32.ulp.ld)
# Replace the separator for the list of ULP source files that will be passed to
# the external ULP project. This is a workaround to the bug https://public.kitware.com/Bug/view.php?id=16137.
string(REPLACE ";" "|" ulp_s_sources "${ulp_s_sources}")
idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER)
idf_build_get_property(idf_path IDF_PATH)
idf_build_get_property(python PYTHON)
externalproject_add(${app_name}
SOURCE_DIR ${idf_path}/components/ulp/cmake
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${app_name}
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}
-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=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES>
-DIDF_PATH=${idf_path}
-DSDKCONFIG=${SDKCONFIG_HEADER}
BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${app_name} --target build
BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources}
${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}
BUILD_ALWAYS 1
LIST_SEPARATOR |
)
spaces2list(exp_dep_srcs)
set_source_files_properties(${exp_dep_srcs} PROPERTIES OBJECT_DEPENDS ${ulp_artifacts})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/${app_name})
add_custom_target(${app_name}_artifacts DEPENDS ${app_name})
add_dependencies(${COMPONENT_LIB} ${app_name}_artifacts)
target_linker_script(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.ld)
target_add_binary_data(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.bin BINARY)
endif()
endfunction()

View File

@ -5,8 +5,7 @@ set(COMPONENT_REQUIRES unity ulp soc esp_common)
register_component()
set(ULP_APP_NAME ulp_test_app)
set(ULP_S_SOURCES "ulp/test_jumps.S")
set(ULP_EXP_DEP_SRCS "test_ulp_as.c")
idf_build_get_property(idf_path IDF_PATH)
include(${idf_path}/components/ulp/component_ulp_common.cmake)
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})

View File

@ -29,27 +29,22 @@ To compile ULP code as part of a component, the following steps must be taken:
.. note: This directory should not be added to the ``COMPONENT_SRCDIRS`` environment variable. The logic behind this is that the ESP-IDF build system will compile files found in ``COMPONENT_SRCDIRS`` based on their extensions. For ``.S`` files, ``xtensa-esp32-elf-as`` assembler is used. This is not desirable for ULP assembly files, so the easiest way to achieve the distinction is by placing ULP assembly files into a separate directory. The ULP assembly source files should also **not** be added to ``COMPONENT_SRCS`` for the same reason. See the step below for how to properly add ULP assembly source files.
2. Modify component CMakeLists.txt, appending the necessary ULP CMake definitions. As an example::
2. Call ``ulp_embed_binary`` from the component CMakeLists.txt after registration. For example::
set(ULP_APP_NAME ulp_${COMPONENT_NAME})
set(ULP_S_SOURCES ulp/ulp_assembly_source_file.S)
set(ULP_EXP_DEP_SRCS "ulp_c_source_file.c")
include(${IDF_PATH}/components/ulp/component_ulp_common.cmake)
...
register_component()
Here is each line explained:
set(ulp_app_name ulp_${COMPONENT_NAME})
set(ulp_s_sources ulp/ulp_assembly_source_file.S)
set(ulp_exp_dep_srcs "ulp_c_source_file.c")
set(ULP_APP_NAME ulp_${COMPONENT_NAME})
Sets the name of the generated ULP application, without an extension. This name is used for build products of the ULP application: ELF file, map file, binary file, generated header file, and generated linker export file.
ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs})
set(ULP_S_SOURCES "ulp/ulp_assembly_source_file_1.S ulp/ulp_assembly_source_file_2.S")
Sets list of assembly files to be passed to the ULP assembler. The list should be space-delimited and the paths can either be absolute or relative to component CMakeLists.txt.
set(ULP_EXP_DEP_SRCS "ulp_c_source_file_1.c ulp_c_source_file_2.c")
Sets list of source files names within the component which include the generated header file. This list is needed to build the dependencies correctly and ensure that the generated header file is created before any of these files are compiled. See section below explaining the concept of generated header files for ULP applications.
The list should be space-delimited and the paths can either be absolute or relative to component CMakeLists.txt.
include(${IDF_PATH}/components/ulp/component_ulp_common.cmake)
Includes common definitions of ULP build steps. Configures build for ULP object files, ELF file, binary file, etc using the ULP toolchain.
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.
Finally, the third argument specifies the list of component source files which include the header file to be generated.
This list is needed to build the dependencies correctly and ensure that the generated header file is created before any of these files are compiled.
See section below explaining the concept of generated header files for ULP applications.
3. Build the application as usual (e.g. `idf.py app`)

View File

@ -6,22 +6,20 @@ set(COMPONENT_REQUIRES soc nvs_flash ulp)
register_component()
#
# ULP support additions to component makefile.
# ULP support additions to component CMakeLists.txt.
#
# 1. ULP_APP_NAME must be unique (if multiple components use ULP)
# Default value, override if necessary:
set(ULP_APP_NAME ulp_${COMPONENT_NAME})
# 1. The ULP app name must be unique (if multiple components use ULP).
set(ulp_app_name ulp_${COMPONENT_NAME})
#
# 2. Specify all assembly source files here.
# 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")
#
# 3. List all the component source files which include automatically
# generated ULP export file, $(ULP_APP_NAME).h:
set(ULP_EXP_DEP_SRCS "ulp_example_main.c")
# generated ULP export file, ${ulp_app_name}.h:
set(ulp_exp_dep_srcs "ulp_example_main.c")
#
# 4. Include build rules for ULP program
# End of ULP support additions to component makefile.
#
include(${IDF_PATH}/components/ulp/component_ulp_common.cmake)
# 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})

View File

@ -6,22 +6,20 @@ set(COMPONENT_REQUIRES soc nvs_flash ulp driver)
register_component()
#
# ULP support additions to component makefile.
# ULP support additions to component CMakeLists.txt.
#
# 1. ULP_APP_NAME must be unique (if multiple components use ULP)
# Default value, override if necessary:
set(ULP_APP_NAME ulp_${COMPONENT_NAME})
# 1. The ULP app name must be unique (if multiple components use ULP).
set(ulp_app_name ulp_${COMPONENT_NAME})
#
# 2. Specify all assembly source files here.
# 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/adc.S")
set(ulp_s_sources "ulp/adc.S")
#
# 3. List all the component source files which include automatically
# generated ULP export file, $(ULP_APP_NAME).h:
set(ULP_EXP_DEP_SRCS "ulp_adc_example_main.c")
# generated ULP export file, ${ulp_app_name}.h:
set(ulp_exp_dep_srcs "ulp_adc_example_main.c")
#
# 4. Include build rules for ULP program
# End of ULP support additions to component makefile.
#
include(${IDF_PATH}/components/ulp/component_ulp_common.cmake)
# 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})