cmake_minimum_required(VERSION 3.16) include(${IDF_PATH}/tools/cmake/utilities.cmake) project(${ULP_APP_NAME} ASM C) add_executable(${ULP_APP_NAME}) option(ULP_COCPU_IS_RISCV "Use RISC-V based ULP" OFF) set(version_pattern "[a-z0-9\.-]+") # Check assembler version execute_process( COMMAND ${CMAKE_ASM_COMPILER} --version OUTPUT_VARIABLE as_output ERROR_QUIET) string(REGEX MATCH "\\(GNU Binutils\\) (${version_pattern})" as_version ${as_output}) set(as_version ${CMAKE_MATCH_1}) message(STATUS "Building ULP app ${ULP_APP_NAME}") # Check the supported assembler version if(NOT ULP_COCPU_IS_RISCV) message(STATUS "ULP assembler version: ${as_version}") set(as_supported_version 2.28.51-esp-20191205) if(NOT as_version STREQUAL as_supported_version) message(WARNING "WARNING: ULP assembler version ${as_version} is not supported. Expected to see version: \ ${as_supported_version}. Please check ESP-IDF ULP setup instructions and update \ the toolchain, or proceed at your own risk.") endif() endif() if(ULP_COCPU_IS_RISCV) set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_riscv.ld) else() set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_fsm.ld) endif() set(ULP_MAP_GEN ${PYTHON} ${IDF_PATH}/components/ulp/esp32ulp_mapgen.py) get_filename_component(sdkconfig_dir ${SDKCONFIG_HEADER} DIRECTORY) foreach(include ${COMPONENT_INCLUDES}) list(APPEND component_includes -I${include}) endforeach() list(APPEND ULP_PREPROCESSOR_ARGS ${component_includes}) list(APPEND ULP_PREPROCESSOR_ARGS -I${COMPONENT_DIR}) list(APPEND ULP_PREPROCESSOR_ARGS -I${sdkconfig_dir}) target_include_directories(${ULP_APP_NAME} PRIVATE ${COMPONENT_INCLUDES}) list(APPEND ULP_PREPROCESSOR_ARGS -D__ASSEMBLER__) # Preprocess linker script, pre-linking get_filename_component(ULP_LD_SCRIPT ${ULP_LD_TEMPLATE} NAME) add_custom_command(OUTPUT ${ULP_LD_SCRIPT} COMMAND ${CMAKE_C_COMPILER} -E -P -xc -o ${ULP_LD_SCRIPT} ${ULP_PREPROCESSOR_ARGS} ${ULP_LD_TEMPLATE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${ULP_LD_TEMPLATE} ${SDKCONFIG_HEADER} VERBATIM) add_custom_target(${ULP_APP_NAME}_ld_script DEPENDS ${ULP_LD_SCRIPT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # To avoid warning "Manually-specified variables were not used by the project" set(bypassWarning "${IDF_TARGET}") if(ULP_COCPU_IS_RISCV) #risc-v ulp uses extra files for building: list(APPEND ULP_S_SOURCES "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/start.S" "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_adc.c" "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_lock.c" "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_uart.c" "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c" "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c") #dummy loop to force pre-processed linker file generation: foreach(ulp_s_source ${ULP_S_SOURCES}) set(noop ${ulp_s_source}) add_custom_command(OUTPUT ${noop} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND cmake -E echo DEPENDS ${ULP_LD_SCRIPT} ) set_source_files_properties(${noop} PROPERTIES NOOP_PROPERTY ${ULP_LD_SCRIPT}) endforeach() set(DUMP_SYMBOL_ARGS -g) set(MAP_GEN_EXTRA_ARGS --riscv) target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles") target_link_options(${ULP_APP_NAME} PRIVATE -Wl,--gc-sections) target_link_options(${ULP_APP_NAME} PRIVATE -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map) target_sources(${ULP_APP_NAME} PRIVATE ${ULP_S_SOURCES}) #Makes the csr utillies for riscv visible: target_include_directories(${ULP_APP_NAME} PRIVATE "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/include" "${IDF_PATH}/components/ulp/ulp_riscv/shared/include") target_link_options(${ULP_APP_NAME} PRIVATE -T ${IDF_PATH}/components/ulp/ld/${IDF_TARGET}.periperals.ld) target_compile_definitions(${ULP_APP_NAME} PRIVATE IS_ULP_COCPU) else() 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_ps_source}.ulp.S) # Generate preprocessed assembly files. add_custom_command(OUTPUT ${ulp_ps_output} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_C_COMPILER} -E -P -xc ${ULP_PREPROCESSOR_ARGS} -o ${ulp_ps_output} ${ulp_s_source} DEPENDS ${ulp_s_source} ${ULP_LD_SCRIPT} VERBATIM) # During assembly file compilation, output listing files as well. set_source_files_properties(${ulp_ps_output} PROPERTIES COMPILE_FLAGS "-al=${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.lst") list(APPEND ULP_PS_SOURCES ${ulp_ps_output}) endforeach() set(DUMP_SYMBOL_ARGS -g -f posix) set(MAP_GEN_EXTRA_ARGS .) target_link_options(${ULP_APP_NAME} PRIVATE -Map=${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map) target_sources(${ULP_APP_NAME} PRIVATE ${ULP_PS_SOURCES}) endif() # Dump the list of global symbols in a convenient format add_custom_command(OUTPUT ${ULP_APP_NAME}.sym COMMAND ${CMAKE_NM} ${DUMP_SYMBOL_ARGS} $ > ${ULP_APP_NAME}.sym DEPENDS ${ULP_APP_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # Dump the binary for inclusion into the project add_custom_command(OUTPUT ${ULP_APP_NAME}.bin COMMAND ${CMAKE_OBJCOPY} -O binary $ ${ULP_APP_NAME}.bin DEPENDS ${ULP_APP_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command(OUTPUT ${ULP_APP_NAME}.ld ${ULP_APP_NAME}.h COMMAND ${ULP_MAP_GEN} ${MAP_GEN_EXTRA_ARGS} -s ${ULP_APP_NAME}.sym -o ${ULP_APP_NAME} DEPENDS ${ULP_APP_NAME}.sym WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # Building the component separately from the project should result in # ULP files being built. add_custom_target(build DEPENDS ${ULP_APP_NAME} ${ULP_APP_NAME}.bin ${ULP_APP_NAME}.sym ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.ld ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.h WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(${ULP_APP_NAME} "-T\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_LD_SCRIPT}\"") set_target_properties(${ULP_APP_NAME} PROPERTIES LINK_DEPENDS ${ULP_LD_SCRIPT})