From 0cbb4227b2bdc794aa185d65fde53ecbcc9556d6 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 30 Jan 2023 18:03:59 +0800 Subject: [PATCH] feature: add build framework support --- Kconfig | 35 ++++-- components/esptool_py/CMakeLists.txt | 15 +-- components/esptool_py/Kconfig.projbuild | 1 + components/esptool_py/project_include.cmake | 113 +++++++++++------- components/partition_table/CMakeLists.txt | 2 +- sdkconfig.rename | 1 + tools/ci/test_build_system_cmake.sh | 2 +- tools/cmake/project.cmake | 6 + tools/cmake/project_description.json.in | 1 + .../gdb_loadable_elf/sdkconfig.defaults | 2 +- 10 files changed, 115 insertions(+), 63 deletions(-) diff --git a/Kconfig b/Kconfig index c830a0f28d..7036d12324 100644 --- a/Kconfig +++ b/Kconfig @@ -141,13 +141,15 @@ mainmenu "Espressif IoT Development Framework Configuration" Another option, useful for only very small and limited applications, is to only link the .elf file of the application, such that it can be loaded directly into RAM over - JTAG. Note that since IRAM and DRAM sizes are very limited, it is not possible to - build any complex application this way. However for kinds of testing and debugging, + JTAG or UART. Note that since IRAM and DRAM sizes are very limited, it is not possible + to build any complex application this way. However for some kinds of testing and debugging, this option may provide faster iterations, since the application does not need to be written into flash. - Note that at the moment, ESP-IDF does not contain all the startup code required to - initialize the CPUs and ROM memory (data/bss). Therefore it is necessary to execute - a bit of ROM code prior to executing the application. A gdbinit file may look as follows (for ESP32): + + Note: when APP_BUILD_TYPE_RAM is selected and loaded with JTAG, ESP-IDF does not contain + all the startup code required to initialize the CPUs and ROM memory (data/bss). + Therefore it is necessary to execute a bit of ROM code prior to executing the application. + A gdbinit file may look as follows (for ESP32): # Connect to a running instance of OpenOCD target remote :3333 @@ -169,6 +171,13 @@ mainmenu "Espressif IoT Development Framework Configuration" Example gdbinit files for other targets can be found in tools/test_apps/system/gdb_loadable_elf/ + When loading the BIN with UART, the ROM will jump to ram and run the app after finishing the ROM + startup code, so there's no additional startup initialization required. You can use the + `load_ram` in esptool.py to load the generated .bin file into ram and execute. + + Example: + esptool.py --chip {chip} -p {port} -b {baud} --no-stub load_ram {app.bin} + Recommended sdkconfig.defaults for building loadable ELF files is as follows. CONFIG_APP_BUILD_TYPE_RAM is required, other options help reduce application memory footprint. @@ -189,9 +198,11 @@ mainmenu "Espressif IoT Development Framework Configuration" select APP_BUILD_BOOTLOADER select APP_BUILD_USE_FLASH_SECTIONS - config APP_BUILD_TYPE_ELF_RAM + config APP_BUILD_TYPE_RAM bool - prompt "ELF file, loadable into RAM (EXPERIMENTAL))" + prompt "Build app runs entirely in RAM (EXPERIMENTAL)" + select APP_BUILD_GENERATE_BINARIES + endchoice # APP_BUILD_TYPE # Hidden options, set according to the choice above @@ -201,6 +212,16 @@ mainmenu "Espressif IoT Development Framework Configuration" config APP_BUILD_BOOTLOADER bool # Whether to build the bootloader + config APP_BUILD_TYPE_PURE_RAM_APP + bool + prompt "Build app without SPI_FLASH/PSRAM support (saves ram)" + depends on APP_BUILD_TYPE_RAM + help + If this option is enabled, external memory and related peripherals, such as Cache, MMU, + Flash and PSRAM, won't be initialized. Corresponding drivers won't be introduced either. + Components that depend on the spi_flash component will also be unavailable, such as + app_update, etc. When this option is enabled, about 26KB of RAM space can be saved. + config APP_BUILD_USE_FLASH_SECTIONS bool # Whether to place code/data into memory-mapped flash sections diff --git a/components/esptool_py/CMakeLists.txt b/components/esptool_py/CMakeLists.txt index 094da4d240..1497be79f5 100644 --- a/components/esptool_py/CMakeLists.txt +++ b/components/esptool_py/CMakeLists.txt @@ -48,13 +48,14 @@ consist of two ota app without factory or test partitions.") CONTENT "${flasher_args_content}") file_generate("${CMAKE_BINARY_DIR}/flasher_args.json" INPUT "${CMAKE_CURRENT_BINARY_DIR}/flasher_args.json.in") - - # Generate app_check_size_command target to check the app size against the partition table parameters - partition_table_add_check_size_target(app_check_size - DEPENDS gen_project_binary - BINARY_PATH "${build_dir}/${PROJECT_BIN}" - PARTITION_TYPE app) - add_dependencies(app app_check_size) + if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) + # Generate app_check_size_command target to check the app size against the partition table parameters + partition_table_add_check_size_target(app_check_size + DEPENDS gen_project_binary + BINARY_PATH "${build_dir}/${PROJECT_BIN}" + PARTITION_TYPE app) + add_dependencies(app app_check_size) + endif() endif() endif() # NOT BOOTLOADER_BUILD diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 3b74136093..b091de1ebe 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -1,4 +1,5 @@ menu "Serial flasher config" + depends on !APP_BUILD_TYPE_PURE_RAM_APP config ESPTOOLPY_NO_STUB bool "Disable download stub" diff --git a/components/esptool_py/project_include.cmake b/components/esptool_py/project_include.cmake index 709c007960..0e52d0c9c4 100644 --- a/components/esptool_py/project_include.cmake +++ b/components/esptool_py/project_include.cmake @@ -19,58 +19,75 @@ 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} "${idf_path}/tools/idf_monitor.py") - -if(CONFIG_SPI_FLASH_HPM_ENABLE) -# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode -# because on some flash chips, 120M will modify the status register, -# which will make ROM won't work. -# This change intends to be for esptool only and the bootloader should keep use -# ``DOUT`` mode. - set(ESPFLASHMODE "dout") - message("Note: HPM is enabled for the flash, force the ROM bootloader into DOUT mode for stable boot on") -else() - set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE}) -endif() -set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ}) -set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE}) - set(ESPTOOLPY_CHIP "${chip_model}") -set(esptool_elf2image_args - --flash_mode ${ESPFLASHMODE} - --flash_freq ${ESPFLASHFREQ} - --flash_size ${ESPFLASHSIZE} - ) - -if(BOOTLOADER_BUILD AND CONFIG_SECURE_BOOT_V2_ENABLED) - # The bootloader binary needs to be 4KB aligned in order to append a secure boot V2 signature block. - # If CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is NOT set, the bootloader - # image generated is not 4KB aligned for external HSM to sign it readily. - # Following esptool option --pad-to-size 4KB generates a 4K aligned bootloader image. - # In case of signing during build, espsecure.py "sign_data" operation handles the 4K alignment of the image. - if(NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES) - list(APPEND esptool_elf2image_args --pad-to-size 4KB) +if(NOT CONFIG_APP_BUILD_TYPE_RAM AND CONFIG_APP_BUILD_GENERATE_BINARIES) + if(CONFIG_SPI_FLASH_HPM_ENABLE) + # When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode + # because on some flash chips, 120M will modify the status register, + # which will make ROM won't work. + # This change intends to be for esptool only and the bootloader should keep use + # ``DOUT`` mode. + set(ESPFLASHMODE "dout") + message("Note: HPM is enabled for the flash, force the ROM bootloader into DOUT mode for stable boot on") + else() + set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE}) endif() -endif() + set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ}) + set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE}) -set(MMU_PAGE_SIZE ${CONFIG_MMU_PAGE_MODE}) -if(NOT BOOTLOADER_BUILD) - list(APPEND esptool_elf2image_args --elf-sha256-offset 0xb0) - # For chips that support configurable MMU page size feature - # If page size is configured to values other than the default "64KB" in menuconfig, - # then we need to pass the actual size to flash-mmu-page-size arg - if(NOT MMU_PAGE_SIZE STREQUAL "64KB") - list(APPEND esptool_elf2image_args --flash-mmu-page-size ${MMU_PAGE_SIZE}) + set(esptool_elf2image_args + --flash_mode ${ESPFLASHMODE} + --flash_freq ${ESPFLASHFREQ} + --flash_size ${ESPFLASHSIZE} + ) + + if(BOOTLOADER_BUILD AND CONFIG_SECURE_BOOT_V2_ENABLED) + # The bootloader binary needs to be 4KB aligned in order to append a secure boot V2 signature block. + # If CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is NOT set, the bootloader + # image generated is not 4KB aligned for external HSM to sign it readily. + # Following esptool option --pad-to-size 4KB generates a 4K aligned bootloader image. + # In case of signing during build, espsecure.py "sign_data" operation handles the 4K alignment of the image. + if(NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES) + list(APPEND esptool_elf2image_args --pad-to-size 4KB) + endif() endif() -endif() -if(NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION AND - NOT BOOTLOADER_BUILD) - if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) - list(APPEND esptool_elf2image_args --secure-pad) - elseif(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) - list(APPEND esptool_elf2image_args --secure-pad-v2) + set(MMU_PAGE_SIZE ${CONFIG_MMU_PAGE_MODE}) + + if(NOT BOOTLOADER_BUILD) + list(APPEND esptool_elf2image_args --elf-sha256-offset 0xb0) + # For chips that support configurable MMU page size feature + # If page size is configured to values other than the default "64KB" in menuconfig, + # then we need to pass the actual size to flash-mmu-page-size arg + if(NOT MMU_PAGE_SIZE STREQUAL "64KB") + list(APPEND esptool_elf2image_args --flash-mmu-page-size ${MMU_PAGE_SIZE}) + endif() + endif() + + if(NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION AND + NOT BOOTLOADER_BUILD) + if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) + list(APPEND esptool_elf2image_args --secure-pad) + elseif(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) + list(APPEND esptool_elf2image_args --secure-pad-v2) + endif() + endif() + + if(CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE) + # Set ESPFLASHSIZE to 'detect' *after* esptool_elf2image_args are generated, + # as elf2image can't have 'detect' as an option... + set(ESPFLASHSIZE detect) + + # Flash size detection updates the image header which would invalidate the appended + # SHA256 digest. Therefore, a digest is not appended in that case. + # This argument requires esptool>=4.1. + list(APPEND esptool_elf2image_args --dont-append-digest) + endif() + + if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME) + set(ESPFLASHSIZE keep) endif() endif() @@ -482,7 +499,11 @@ function(esptool_py_custom_target target_name flasher_filename dependencies) endfunction() if(NOT BOOTLOADER_BUILD) - set(flash_deps "partition_table_bin") + set(flash_deps "") + + if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) + list(APPEND flash_deps "partition_table_bin") + endif() if(CONFIG_APP_BUILD_GENERATE_BINARIES) list(APPEND flash_deps "app") diff --git a/components/partition_table/CMakeLists.txt b/components/partition_table/CMakeLists.txt index f386028612..5eaec4d312 100644 --- a/components/partition_table/CMakeLists.txt +++ b/components/partition_table/CMakeLists.txt @@ -144,7 +144,7 @@ endif() idf_component_get_property(main_args esptool_py FLASH_ARGS) idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS) -if(CONFIG_APP_BUILD_GENERATE_BINARIES) +if(CONFIG_APP_BUILD_GENERATE_BINARIES AND CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) esptool_py_flash_target(partition-table-flash "${main_args}" "${sub_args}") esptool_py_flash_target_image(partition-table-flash partition-table "${PARTITION_TABLE_OFFSET}" "${build_dir}/partition_table/${final_partition_bin}") diff --git a/sdkconfig.rename b/sdkconfig.rename index 1b3c415ddf..e0b4d367c9 100644 --- a/sdkconfig.rename +++ b/sdkconfig.rename @@ -23,3 +23,4 @@ CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS CONFIG_NO_BLOBS CONFIG_APP_NO_BLOBS CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS +CONFIG_APP_BUILD_TYPE_ELF_RAM CONFIG_APP_BUILD_TYPE_RAM diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index cbc800c3cc..88cc6f0b49 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -885,7 +885,7 @@ endmenu\n" >> ${IDF_PATH}/Kconfig rm -rf build sdkconfig print_status "Loadable ELF build works" - echo "CONFIG_APP_BUILD_TYPE_ELF_RAM=y" > sdkconfig + echo "CONFIG_APP_BUILD_TYPE_RAM=y" > sdkconfig # Set recommend configs to reduce memory footprint echo "CONFIG_VFS_SUPPORT_TERMIOS=n" >> sdkconfig diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index 7b5e8fb7c9..7852fc41e0 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -153,6 +153,12 @@ function(__project_info test_components) idf_build_get_property(COMPONENT_KCONFIGS_PROJBUILD KCONFIG_PROJBUILDS) idf_build_get_property(debug_prefix_map_gdbinit DEBUG_PREFIX_MAP_GDBINIT) + if(CONFIG_APP_BUILD_TYPE_RAM) + set(PROJECT_BUILD_TYPE ram_app) + else() + set(PROJECT_BUILD_TYPE flash_app) + endif() + # Write project description JSON file idf_build_get_property(build_dir BUILD_DIR) make_json_list("${build_components};${test_components}" build_components_json) diff --git a/tools/cmake/project_description.json.in b/tools/cmake/project_description.json.in index 330c5190a9..5400ac20e4 100644 --- a/tools/cmake/project_description.json.in +++ b/tools/cmake/project_description.json.in @@ -7,6 +7,7 @@ "bootloader_elf": "${BOOTLOADER_ELF_FILE}", "app_elf": "${PROJECT_EXECUTABLE}", "app_bin": "${PROJECT_BIN}", + "build_type": "${PROJECT_BUILD_TYPE}", "git_revision": "${IDF_VER}", "target": "${CONFIG_IDF_TARGET}", "rev": "${CONFIG_ESP32_REV_MIN}", diff --git a/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults b/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults index 331e8d5ef6..b7b5ad9822 100644 --- a/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults +++ b/tools/test_apps/system/gdb_loadable_elf/sdkconfig.defaults @@ -1,4 +1,4 @@ -CONFIG_APP_BUILD_TYPE_ELF_RAM=y +CONFIG_APP_BUILD_TYPE_RAM=y CONFIG_VFS_SUPPORT_TERMIOS=n CONFIG_NEWLIB_NANO_FORMAT=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y