feature: add build framework support

This commit is contained in:
wuzhenghui 2023-01-30 18:03:59 +08:00
parent 44df5b31af
commit 0cbb4227b2
10 changed files with 115 additions and 63 deletions

35
Kconfig
View File

@ -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

View File

@ -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

View File

@ -1,4 +1,5 @@
menu "Serial flasher config"
depends on !APP_BUILD_TYPE_PURE_RAM_APP
config ESPTOOLPY_NO_STUB
bool "Disable download stub"

View File

@ -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")

View File

@ -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}")

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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}",

View File

@ -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