cmake: Allow components to present their own images to flash

This commit is contained in:
Renz Christian Bagaporo 2019-01-22 11:45:45 +08:00
parent 5beb2802e0
commit 234de8de55
14 changed files with 147 additions and 117 deletions

View file

@ -6,7 +6,7 @@ set(COMPONENT_REQUIRES spi_flash partition_table bootloader_support)
register_component()
# esp_app_desc structure is added as an undefined symbol because otherwise the
# esp_app_desc structure is added as an undefined symbol because otherwise the
# linker will ignore this structure as it has no other files depending on it.
target_link_libraries(${COMPONENT_TARGET} "-u esp_app_desc")
@ -16,25 +16,34 @@ string(SUBSTRING "${PROJECT_NAME}" 0 31 PROJECT_NAME_CUT)
set_source_files_properties(
SOURCE "esp_app_desc.c"
PROPERTIES COMPILE_DEFINITIONS
PROPERTIES COMPILE_DEFINITIONS
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
# Add custom target for generating empty otadata partition for flashing
if(OTADATA_PARTITION_OFFSET AND OTADATA_PARTITION_SIZE)
add_custom_command(OUTPUT "${IDF_BUILD_ARTIFACTS_DIR}/${BLANK_OTADATA_FILE}"
COMMAND ${PYTHON} ${IDF_PATH}/components/partition_table/parttool.py
--partition-type data --partition-subtype ota -q
--partition-table-file ${PARTITION_CSV_PATH} generate_blank_partition_file
--output "${IDF_BUILD_ARTIFACTS_DIR}/${BLANK_OTADATA_FILE}")
if (NOT BOOTLOADER_BUILD AND IDF_BUILD_ARTIFACTS)
partition_table_get_partition_info(otadata_offset "--partition-type data --partition-subtype ota" "offset")
partition_table_get_partition_info(otadata_size "--partition-type data --partition-subtype ota" "size")
add_custom_target(blank_ota_data ALL DEPENDS "${IDF_BUILD_ARTIFACTS_DIR}/${BLANK_OTADATA_FILE}")
add_dependencies(flash blank_ota_data)
set(blank_otadata_file ${IDF_BUILD_ARTIFACTS_DIR}/ota_data_initial.bin)
# Add custom target for generating empty otadata partition for flashing
if(otadata_size AND otadata_offset)
add_custom_command(OUTPUT ${blank_otadata_file}
COMMAND ${PYTHON} ${IDF_PATH}/components/partition_table/parttool.py
--partition-type data --partition-subtype ota -q
--partition-table-file ${PARTITION_CSV_PATH} generate_blank_partition_file
--output ${blank_otadata_file})
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})
add_dependencies(flash blank_ota_data)
set(otatool_py ${PYTHON} ${COMPONENT_PATH}/otatool.py)
add_custom_target(read_otadata DEPENDS "${PARTITION_CSV_PATH}"
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} read_otadata)
add_custom_target(erase_otadata DEPENDS "${PARTITION_CSV_PATH}"
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} erase_otadata)
esptool_py_flash_project_args(otadata ${otadata_offset} "${blank_otadata_file}" FLASH_IN_PROJECT)
endif()
endif()
set(otatool_py ${PYTHON} ${COMPONENT_PATH}/otatool.py)
add_custom_target(read_otadata DEPENDS "${PARTITION_CSV_PATH}"
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} read_otadata)
add_custom_target(erase_otadata DEPENDS "${PARTITION_CSV_PATH}"
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} erase_otadata)

View file

@ -1,9 +0,0 @@
# Set empty otadata partition file for flashing, if OTA data partition in
# partition table
# (NB: because of component dependency, we know partition_table
# project_include.cmake has already been included.)
if(OTADATA_PARTITION_OFFSET AND OTADATA_PARTITION_SIZE AND IDF_BUILD_ARTIFACTS)
set(BLANK_OTADATA_FILE "ota_data_initial.bin")
endif()

View file

@ -1,7 +1,12 @@
# bootloader component logic is all in project_include.cmake,
# and subproject/CMakeLists.txt.
#
# This file is only included so the build system finds the
# component
# Do not generate flash file when building bootloader or is in early expansion of the build
if(CMAKE_BUILD_EARLY_EXPANSION OR BOOTLOADER_BUILD)
return()
endif()
# Set values used in flash_bootloader_args.in and generate flash file
# for bootloader
set(BOOTLOADER_OFFSET 0x1000)
esptool_py_flash_project_args(bootloader ${BOOTLOADER_OFFSET}
${BOOTLOADER_BUILD_DIR}/bootloader.bin
FLASH_IN_PROJECT
FLASH_FILE_TEMPLATE flash_bootloader_args.in)

View file

@ -1,4 +1,4 @@
--flash_mode ${ESPFLASHMODE}
--flash_size ${ESPFLASHSIZE}
--flash_freq ${ESPFLASHFREQ}
${BOOTLOADER_OFFSET} bootloader/bootloader.bin
${BOOTLOADER_OFFSET} bootloader/bootloader.bin

View file

@ -27,20 +27,20 @@ endif()
# cmake project under this one
#
#
set(bootloader_build_dir "${IDF_BUILD_ARTIFACTS_DIR}/bootloader")
set(BOOTLOADER_BUILD_DIR "${IDF_BUILD_ARTIFACTS_DIR}/bootloader")
set(bootloader_binary_files
"${bootloader_build_dir}/bootloader.elf"
"${bootloader_build_dir}/bootloader.bin"
"${bootloader_build_dir}/bootloader.map"
"${BOOTLOADER_BUILD_DIR}/bootloader.elf"
"${BOOTLOADER_BUILD_DIR}/bootloader.bin"
"${BOOTLOADER_BUILD_DIR}/bootloader.map"
)
# These additional files may get generated
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
set(bootloader_binary_files
${bootloader_binary_files}
"${bootloader_build_dir}/bootloader-reflash-digest.bin"
"${bootloader_build_dir}/secure-bootloader-key-192.bin"
"${bootloader_build_dir}/secure-bootloader-key-256.bin"
"${BOOTLOADER_BUILD_DIR}/bootloader-reflash-digest.bin"
"${BOOTLOADER_BUILD_DIR}/secure-bootloader-key-192.bin"
"${BOOTLOADER_BUILD_DIR}/secure-bootloader-key-256.bin"
)
endif()
@ -50,7 +50,7 @@ if((NOT CONFIG_SECURE_BOOT_ENABLED) OR
externalproject_add(bootloader
# TODO: support overriding the bootloader in COMPONENT_PATHS
SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
BINARY_DIR "${bootloader_build_dir}"
BINARY_DIR "${BOOTLOADER_BUILD_DIR}"
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}
INSTALL_COMMAND ""

View file

@ -134,21 +134,24 @@ else()
add_dependencies(${COMPONENT_TARGET} esp32_linker_script)
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION AND IDF_BUILD_ARTIFACTS)
set(PHY_INIT_DATA_BIN ${IDF_BUILD_ARTIFACTS_DIR}/${PHY_PARTITION_BIN_FILE})
partition_table_get_partition_info(phy_partition_offset "--partition-type data --partition-subtype phy" "offset")
set(phy_init_data_bin "${IDF_BUILD_ARTIFACTS_DIR}/phy_init_data.bin")
# To get the phy_init_data.bin file, compile phy_init_data.h as a C file and then objcopy
# the object file to a raw binary
add_custom_command(
OUTPUT ${PHY_INIT_DATA_BIN}
OUTPUT ${phy_init_data_bin}
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h
COMMAND ${CMAKE_C_COMPILER} -x c -c
-I ${CMAKE_CURRENT_LIST_DIR} -I ${CMAKE_CURRENT_LIST_DIR}/include -I ${IDF_BUILD_ARTIFACTS_DIR}
-o phy_init_data.obj
${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h
COMMAND ${CMAKE_OBJCOPY} -O binary phy_init_data.obj ${PHY_INIT_DATA_BIN}
COMMAND ${CMAKE_OBJCOPY} -O binary phy_init_data.obj ${phy_init_data_bin}
)
add_custom_target(phy_init_data ALL DEPENDS ${PHY_INIT_DATA_BIN})
add_custom_target(phy_init_data ALL DEPENDS ${phy_init_data_bin})
add_dependencies(flash phy_init_data)
esptool_py_flash_project_args(phy ${phy_partition_offset} ${phy_init_data_bin} FLASH_IN_PROJECT)
endif()
# Enable dynamic esp_timer overflow value if building unit tests

View file

@ -1,26 +1,27 @@
register_config_only_component()
if(IDF_BUILD_ARTIFACTS)
string(REPLACE ";" " " ESPTOOLPY_FLASH_PROJECT_OPTIONS "${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS}")
set(ESPTOOLPY_FLASH_PROJECT_OPTIONS
"${ESPTOOLPY_FLASH_PROJECT_OPTIONS} ${BOOTLOADER_OFFSET} bootloader/bootloader.bin"
"${ESPTOOLPY_FLASH_PROJECT_OPTIONS}"
)
if(CONFIG_SECURE_BOOT_ENABLED)
set(ESPTOOLPY_FLASH_PROJECT_OPTIONS "")
endif()
if(IDF_BUILD_ARTIFACTS)
# Generate pre-canned flasher args files suitable for passing to esptool.py
foreach(part project app bootloader partition_table)
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/flash_${part}_args.in"
"${IDF_BUILD_ARTIFACTS_DIR}/flash_${part}_args"
)
endforeach()
# Generate the flash project args and the flasher args json file using the accumulated values
# from esptool_py_flash_project_args calls. The file is first configured using configure_file() for all variable values,
# and then generated using file(GENERATE... for generator expressions.
configure_file(${COMPONENT_PATH}/flash_project_args.in
${CMAKE_CURRENT_BINARY_DIR}/flash_project_args.in)
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/flasher_args.json.in"
"${IDF_BUILD_ARTIFACTS_DIR}/flasher_args.json"
)
endif()
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/flash_project_args
INPUT ${CMAKE_CURRENT_BINARY_DIR}/flash_project_args.in)
configure_file(${COMPONENT_PATH}/flasher_args.json.in
${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json.in)
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/flasher_args.json
INPUT ${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json.in)
endif()

View file

@ -1 +0,0 @@
${APP_PARTITION_OFFSET} ${IDF_PROJECT_BIN}

View file

@ -1 +0,0 @@
${PARTITION_TABLE_OFFSET} partition_table/partition-table.bin

View file

@ -1,6 +1,3 @@
${ESPTOOLPY_FLASH_PROJECT_OPTIONS}
${PARTITION_TABLE_OFFSET} partition_table/partition-table.bin
${PHY_PARTITION_OFFSET} ${PHY_PARTITION_BIN_FILE}
${OTADATA_PARTITION_OFFSET} ${BLANK_OTADATA_FILE}
${APP_PARTITION_OFFSET} ${IDF_PROJECT_BIN}
$<JOIN:$<TARGET_PROPERTY:flash_project_args_target,FLASH_PROJECT_ARGS>,
>

View file

@ -8,20 +8,11 @@
"flash_freq": "${ESPFLASHFREQ}"
},
"flash_files" : {
"${BOOTLOADER_OFFSET}" : "bootloader/bootloader.bin",
"${PARTITION_TABLE_OFFSET}" : "partition_table/partition-table.bin",
"${PHY_PARTITION_OFFSET}" : "${PHY_PARTITION_BIN_FILE}",
"${OTADATA_PARTITION_OFFSET}" : "${BLANK_OTADATA_FILE}",
"${APP_PARTITION_OFFSET}" : "${IDF_PROJECT_BIN}"
$<JOIN:$<TARGET_PROPERTY:flash_project_args_target,FLASH_PROJECT_ARGS_JSON>,,
>
},
"bootloader" : { "offset" : "${BOOTLOADER_OFFSET}",
"file" : "bootloader/bootloader.bin" },
"partition_table" : { "offset" : "${PARTITION_TABLE_OFFSET}",
"file" : "partition_table/partition-table.bin" },
"otadata" : { "offset" : "${OTADATA_PARTITION_OFFSET}",
"file" : "${BLANK_OTADATA_FILE}" },
"app" : { "offset" : "${APP_PARTITION_OFFSET}",
"file" : "${IDF_PROJECT_BIN}" },
$<JOIN:$<TARGET_PROPERTY:flash_project_args_target,FLASH_PROJECT_ARGS_ENTRY_JSON>,,
>,
"extra_esptool_args" : {
"after" : "${ESPTOOLPY_AFTER}",
"before" : "${ESPTOOLPY_BEFORE}"

View file

@ -60,12 +60,6 @@ if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
set(ESPFLASHSIZE detect)
endif()
# Set variables if the PHY data partition is in the flash
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
set(PHY_PARTITION_OFFSET ${CONFIG_PHY_DATA_OFFSET})
set(PHY_PARTITION_BIN_FILE "esp32/phy_init_data.bin")
endif()
get_filename_component(IDF_PROJECT_NAME ${IDF_PROJECT_EXECUTABLE} NAME_WE)
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES AND NOT BOOTLOADER_BUILD)
set(unsigned_project_binary "${IDF_PROJECT_NAME}-unsigned.bin")
@ -136,3 +130,55 @@ endfunction()
esptool_py_custom_target(flash project "app;partition_table;bootloader")
esptool_py_custom_target(app-flash app "app")
esptool_py_custom_target(bootloader-flash bootloader "bootloader")
add_custom_target(flash_project_args_target)
# esptool_py_flash_project_args
#
# Add file to the flasher args list, to be flashed at a particular offset
function(esptool_py_flash_project_args entry offset image)
set(options FLASH_IN_PROJECT) # flash the image when flashing the project
set(single_value FLASH_FILE_TEMPLATE) # template file to use to be able to
# flash the image individually using esptool
cmake_parse_arguments(flash_entry "${options}" "${single_value}" "" "${ARGN}")
get_property(flash_project_entries TARGET flash_project_args_target PROPERTY FLASH_PROJECT_ENTRIES)
if(${entry} IN_LIST flash_project_entries)
message(FATAL_ERROR "entry '${entry}' has already been added to flash project entries")
endif()
list(APPEND flash_project_entries "${entry}")
set_property(TARGET flash_project_args_target PROPERTY FLASH_PROJECT_ENTRIES "${flash_project_entries}")
file(RELATIVE_PATH image ${CMAKE_BINARY_DIR} ${image})
# Generate the standalone flash file to flash the image individually using esptool
set(entry_flash_args ${IDF_BUILD_ARTIFACTS_DIR}/flash_${entry}_args)
if(NOT flash_entry_FLASH_FILE_TEMPLATE)
file(GENERATE OUTPUT ${entry_flash_args} CONTENT "${offset} ${image}")
else()
configure_file(${flash_entry_FLASH_FILE_TEMPLATE} ${entry_flash_args})
endif()
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${entry_flash_args})
# Generate standalone entries in the flasher args json file
get_property(flash_project_args_entry_json TARGET
flash_project_args_target PROPERTY FLASH_PROJECT_ARGS_ENTRY_JSON)
list(APPEND flash_project_args_entry_json
"\"${entry}\" : { \"offset\" : \"${offset}\", \"file\" : \"${image}\" }")
set_property(TARGET flash_project_args_target
PROPERTY FLASH_PROJECT_ARGS_ENTRY_JSON "${flash_project_args_entry_json}")
# Generate entries in the flasher args json file
if(flash_entry_FLASH_IN_PROJECT)
get_property(flash_project_args TARGET flash_project_args_target PROPERTY FLASH_PROJECT_ARGS)
list(APPEND flash_project_args "${offset} ${image}")
set_property(TARGET flash_project_args_target PROPERTY FLASH_PROJECT_ARGS "${flash_project_args}")
get_property(flash_project_args_json TARGET flash_project_args_target PROPERTY FLASH_PROJECT_ARGS_JSON)
list(APPEND flash_project_args_json "\"${offset}\" : \"${image}\"")
set_property(TARGET flash_project_args_target PROPERTY FLASH_PROJECT_ARGS_JSON "${flash_project_args_json}")
endif()
endfunction()

View file

@ -29,7 +29,7 @@ else()
endif()
add_custom_command(OUTPUT "${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${unsigned_partition_bin}"
COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
-q --offset ${PARTITION_TABLE_OFFSET} ${md5_opt} ${flashsize_opt}
${partition_secure_opt} ${partition_csv} ${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${unsigned_partition_bin}
DEPENDS ${partition_csv} "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
@ -37,12 +37,12 @@ add_custom_command(OUTPUT "${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${unsigned
# Add signing steps
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
add_custom_target(gen_unsigned_partition_bin ALL DEPENDS
add_custom_target(gen_unsigned_partition_bin ALL DEPENDS
"${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${unsigned_partition_bin}")
add_custom_command(OUTPUT "${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${final_partition_bin}"
COMMAND ${ESPSECUREPY} sign_data --keyfile "${secure_boot_signing_key}"
-o "${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${final_partition_bin}"
-o "${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${final_partition_bin}"
"${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${unsigned_partition_bin}"
DEPENDS "${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${unsigned_partition_bin}"
VERBATIM)
@ -87,5 +87,13 @@ set_property(GLOBAL APPEND_STRING PROPERTY
ESPTOOL_WRITE_FLASH_ARGS
"${PARTITION_TABLE_OFFSET} ${IDF_BUILD_ARTIFACTS_DIR}/partition_table/${final_partition_bin} ")
esptool_py_flash_project_args(partition_table ${PARTITION_TABLE_OFFSET}
${IDF_BUILD_ARTIFACTS_DIR}/partition_table/partition-table.bin FLASH_IN_PROJECT)
if (NOT BOOTLOADER_BUILD)
partition_table_get_partition_info(app_partition_offset "--partition-boot-default" "offset")
esptool_py_flash_project_args(app ${app_partition_offset} ${CMAKE_BINARY_DIR}/${IDF_PROJECT_BIN} FLASH_IN_PROJECT)
endif()
endif()

View file

@ -1,5 +1,4 @@
if(NOT BOOTLOADER_BUILD AND IDF_BUILD_ARTIFACTS)
if(NOT BOOTLOADER_BUILD)
set(PARTITION_TABLE_OFFSET ${CONFIG_PARTITION_TABLE_OFFSET})
# Set PARTITION_CSV_PATH to the configured partition CSV file
@ -27,42 +26,24 @@ endif()
# need to re-run CMake if the partition CSV changes, as the offsets/sizes of partitions may change
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PARTITION_CSV_PATH})
# Parse the partition table to get variable partition offsets & sizes which must be known at CMake runtime
function(get_partition_info variable get_part_info_args part_info)
# partition_table_get_partition_info
#
# Get information about a partition from the partition table
function(partition_table_get_partition_info result get_part_info_args part_info)
separate_arguments(get_part_info_args)
execute_process(COMMAND ${PYTHON}
${COMPONENT_PATH}/parttool.py -q
${IDF_PATH}/components/partition_table/parttool.py -q
--partition-table-offset ${PARTITION_TABLE_OFFSET}
--partition-table-file ${PARTITION_CSV_PATH}
${get_part_info_args} get_partition_info --info ${part_info}
OUTPUT_VARIABLE result
OUTPUT_VARIABLE info
RESULT_VARIABLE exit_code
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${exit_code} EQUAL 0 AND NOT ${exit_code} EQUAL 1)
# can't fail here as it would prevent the user from running 'menuconfig' again
message(WARNING "parttool.py execution failed (${result}), problem with partition CSV file (see above)")
endif()
set(${variable} ${result} PARENT_SCOPE)
set(${result} ${info} PARENT_SCOPE)
endfunction()
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
get_partition_info(PHY_PARTITION_OFFSET
"--partition-type data --partition-subtype phy" "offset")
set(PHY_PARTITION_BIN_FILE "esp32/phy_init_data.bin")
endif()
get_partition_info(APP_PARTITION_OFFSET
"--partition-boot-default" "offset")
get_partition_info(OTADATA_PARTITION_OFFSET
"--partition-type data --partition-subtype ota" "offset")
get_partition_info(OTADATA_PARTITION_SIZE
"--partition-type data --partition-subtype ota" "size")
get_partition_info(FACTORY_OFFSET
"--partition-type app --partition-subtype factory" "offset")
endif()
set(BOOTLOADER_OFFSET 0x1000)