rm -rf "$CUSTOM_TOOLCHAIN_PATH"
.setup_tools_unless_target_test: &setup_tools_unless_target_test |
- if [ "$CI_JOB_STAGE" != "target_test" ]; then
+ if [[ "$SETUP_TOOLS" == "1" || "$CI_JOB_STAGE" != "target_test" ]]; then
tools/idf_tools.py --non-interactive install && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1
fi
endmenu # SDK tool configuration
+ menu "Build type"
+
+ choice APP_BUILD_TYPE
+ prompt "Application build type"
+ default APP_BUILD_TYPE_APP_2NDBOOT
+ help
+ Select the way the application is built.
+
+ By default, the application is built as a binary file in a format compatible with
+ the ESP32 bootloader. In addition to this application, 2nd stage bootloader is
+ also built. Application and bootloader binaries can be written into flash and
+ loaded/executed from there.
+
+ 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,
+ 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:
+
+ # Connect to a running instance of OpenOCD
+ target remote :3333
+ # Reset and halt the target
+ mon reset halt
+ # Run to a specific point in ROM code,
+ # where most of initialization is complete.
+ thb *0x40007901
+ c
+ # Load the application into RAM
+ load
+ # Run till app_main
+ tb app_main
+ c
+
+ Execute this gdbinit file as follows:
+
+ xtensa-esp32-elf-gdb build/app-name.elf -x gdbinit
+
+ Recommended sdkconfig.defaults for building loadable ELF files is as follows.
+ CONFIG_APP_BUILD_TYPE_ELF_RAM is required, other options help reduce application
+ memory footprint.
+
+ CONFIG_APP_BUILD_TYPE_ELF_RAM=y
+ CONFIG_VFS_SUPPORT_TERMIOS=
+ CONFIG_NEWLIB_NANO_FORMAT=y
+ CONFIG_ESP32_PANIC_PRINT_HALT=y
+ CONFIG_ESP32_DEBUG_STUBS_ENABLE=
+ CONFIG_ESP_ERR_TO_NAME_LOOKUP=
+
+
+ config APP_BUILD_TYPE_APP_2NDBOOT
+ bool
+ prompt "Default (binary application + 2nd stage bootloader)"
+ select APP_BUILD_GENERATE_BINARIES
+ select APP_BUILD_BOOTLOADER
+ select APP_BUILD_USE_FLASH_SECTIONS
+
+ config APP_BUILD_TYPE_ELF_RAM
+ bool
+ prompt "ELF file, loadable into RAM (EXPERIMENTAL))"
+ endchoice # APP_BUILD_TYPE
+
+ # Hidden options, set according to the choice above
+ config APP_BUILD_GENERATE_BINARIES
+ bool # Whether to generate .bin files or not
+
+ config APP_BUILD_BOOTLOADER
+ bool # Whether to build the bootloader
+
+ config APP_BUILD_USE_FLASH_SECTIONS
+ bool # Whether to place code/data into memory-mapped flash sections
+
+ endmenu # Build type
+
source "$COMPONENT_KCONFIGS_PROJBUILD"
menu "Compiler options"
idf_component_register(PRIV_REQUIRES partition_table)
# Do not generate flash file when building bootloader or is in early expansion of the build
-if(BOOTLOADER_BUILD)
+if(BOOTLOADER_BUILD OR NOT CONFIG_APP_BUILD_BOOTLOADER)
return()
endif()
set(BOOTLOADER_OFFSET 0x1000)
# Do not generate flash file when building bootloader
-if(BOOTLOADER_BUILD)
+if(BOOTLOADER_BUILD OR NOT CONFIG_APP_BUILD_BOOTLOADER)
return()
endif()
# So for now we just have the top-level build remove the final build products...
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
- ${bootloader_binary_files})
\ No newline at end of file
+ ${bootloader_binary_files})
Enabling this setting adds approximately 1KB to the app's IRAM usage.
+ config ESP32_APP_INIT_CLK
+ bool
+ default y if ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS
+ default y if APP_BUILD_TYPE_ELF_RAM
+
config ESP32_RTCDATA_IN_FAST_MEM
bool "Place RTC_DATA_ATTR and RTC_RODATA_ATTR variables into RTC fast memory segment"
default n
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
rtc_init(cfg);
-#ifdef CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS
+#if (CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS || CONFIG_ESP32_APP_INIT_CLK)
/* Check the bootloader set the XTAL frequency.
Bootloaders pre-v2.1 don't do this.
DPORT_I2S1_CLK_EN |
DPORT_SPI_DMA_CLK_EN;
+ common_perip_clk &= ~DPORT_SPI01_CLK_EN;
+
#if CONFIG_SPIRAM_SPEED_80M
//80MHz SPIRAM uses SPI2/SPI3 as well; it's initialized before this is called. Because it is used in
//a weird mode where clock to the peripheral is disabled but reset is also disabled, it 'hangs'
#include "esp_efuse.h"
#include "bootloader_flash_config.h"
+#ifdef CONFIG_APP_BUILD_TYPE_ELF_RAM
+#include "esp32/rom/efuse.h"
+#include "esp32/rom/spi_flash.h"
+#endif // CONFIG_APP_BUILD_TYPE_ELF_RAM
+
#define STRINGIFY(s) STRINGIFY2(s)
#define STRINGIFY2(s) #s
#ifndef CONFIG_FREERTOS_UNICORE
esp_dport_access_int_init();
#endif
+
+ bootloader_flash_update_id();
+#if !CONFIG_SPIRAM_BOOT_INIT
+ // Read the application binary image header. This will also decrypt the header if the image is encrypted.
+ esp_image_header_t fhdr = {0};
+#ifdef CONFIG_APP_BUILD_TYPE_ELF_RAM
+ fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO;
+ fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_40M;
+ fhdr.spi_size = ESP_IMAGE_FLASH_SIZE_4MB;
+
+ extern void esp_rom_spiflash_attach(uint32_t, bool);
+ esp_rom_spiflash_attach(ets_efuse_get_spiconfig(), false);
+ esp_rom_spiflash_unlock();
+#else
+ // This assumes that DROM is the first segment in the application binary, i.e. that we can read
+ // the binary header through cache by accessing SOC_DROM_LOW address.
+ memcpy(&fhdr, (void*) SOC_DROM_LOW, sizeof(fhdr));
+#endif // CONFIG_APP_BUILD_TYPE_ELF_RAM
+
+ // If psram is uninitialized, we need to improve some flash configuration.
+ bootloader_flash_clock_config(&fhdr);
+ bootloader_flash_gpio_config(&fhdr);
+ bootloader_flash_dummy_config(&fhdr);
+ bootloader_flash_cs_timing_config();
+#endif //!CONFIG_SPIRAM_BOOT_INIT
+
spi_flash_init();
/* init default OS-aware flash access critical section */
spi_flash_guard_set(&g_flash_guard_default_ops);
esp_coex_adapter_register(&g_coex_adapter_funcs);
#endif
- bootloader_flash_update_id();
-#if !CONFIG_SPIRAM_BOOT_INIT
- // Read the application binary image header. This will also decrypt the header if the image is encrypted.
- esp_image_header_t fhdr = {0};
- // This assumes that DROM is the first segment in the application binary, i.e. that we can read
- // the binary header through cache by accessing SOC_DROM_LOW address.
- memcpy(&fhdr, (void*) SOC_DROM_LOW, sizeof(fhdr));
- // If psram is uninitialized, we need to improve some flash configuration.
- bootloader_flash_clock_config(&fhdr);
- bootloader_flash_gpio_config(&fhdr);
- bootloader_flash_dummy_config(&fhdr);
- bootloader_flash_cs_timing_config();
-#endif
-
portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
ESP_TASK_MAIN_STACK, NULL,
ESP_TASK_MAIN_PRIO, NULL, 0);
/* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000
+#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Even though the segment name is iram, it is actually mapped to flash
*/
iram0_2_seg (RX) : org = 0x400D0018, len = 0x330000-0x18
which is flashed to the chip has a 0x18 byte file header. Setting this offset makes it simple to meet the flash
cache MMU's constraint that (paddr % 64KB == vaddr % 64KB).)
*/
+#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Shared data RAM, excluding memory reserved for ROM bss/data/stack.
dram0_0_seg (RW) : org = 0x3FFB0000 + CONFIG_BT_RESERVE_DRAM,
len = DRAM0_0_SEG_LEN - CONFIG_BT_RESERVE_DRAM
+#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Flash mapped constant data */
drom0_0_seg (R) : org = 0x3F400018, len = 0x400000-0x18
/* (See iram0_2_seg for meaning of 0x18 offset in the above.) */
+#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* RTC fast memory (executable). Persists over deep sleep.
*/
#else
REGION_ALIAS("rtc_data_location", rtc_data_seg );
#endif
+
+#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
+ REGION_ALIAS("default_code_seg", iram0_2_seg);
+#else
+ REGION_ALIAS("default_code_seg", iram0_0_seg);
+#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
+
+#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
+ REGION_ALIAS("default_rodata_seg", drom0_0_seg);
+#else
+ REGION_ALIAS("default_rodata_seg", dram0_0_seg);
+#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
mapping[iram0_text]
_iram_text_end = ABSOLUTE(.);
- _iram_end = ABSOLUTE(.);
} > iram0_0_seg
- ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
- "IRAM0 segment data does not fit.")
-
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.tbss.*)
_thread_local_end = ABSOLUTE(.);
. = ALIGN(4);
- } >drom0_0_seg
+ } >default_rodata_seg
.flash.text :
{
the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
- } >iram0_2_seg
+ } >default_code_seg
+
+ /* Marks the end of IRAM code segment */
+ .iram0.text_end (NOLOAD) :
+ {
+ . = ALIGN (4);
+ _iram_end = ABSOLUTE(.);
+ } > iram0_0_seg
+
+ /* Marks the end of data, bss and possibly rodata */
+ .dram0.heap_start (NOLOAD) :
+ {
+ . = ALIGN (8);
+ _heap_start = ABSOLUTE(.);
+ } > dram0_0_seg
}
+
+ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
+ "IRAM0 segment data does not fit.")
+
+ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
+ "DRAM segment data does not fit.")
[scheme:default]
entries:
- text -> flash_text
- rodata -> flash_rodata
+ if APP_BUILD_USE_FLASH_SECTIONS = y:
+ text -> flash_text
+ rodata -> flash_rodata
+ else:
+ text -> iram0_text
+ rodata -> dram0_data
data -> dram0_data
bss -> dram0_bss
common -> dram0_bss
;
}
}
-#endif
+#endif // CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
static void putEntry(uint32_t pc, uint32_t sp)
{
PROVIDE ( esp_rom_spiflash_erase_block = 0x40062c4c );
PROVIDE ( esp_rom_spiflash_erase_chip = 0x40062c14 );
PROVIDE ( esp_rom_spiflash_erase_sector = 0x40062ccc );
+PROVIDE ( esp_rom_spiflash_attach = 0x40062a6c );
PROVIDE ( esp_rom_spiflash_lock = 0x400628f0 );
PROVIDE ( esp_rom_spiflash_read = 0x40062ed8 );
PROVIDE ( esp_rom_spiflash_config_readmode = 0x40062b64 ); /* SPIMasterReadModeCnfig */
idf_component_register(REQUIRES bootloader)
-if(NOT BOOTLOADER_BUILD)
+if(NOT BOOTLOADER_BUILD AND CONFIG_APP_BUILD_GENERATE_BINARIES)
string(REPLACE ";" " " ESPTOOLPY_FLASH_PROJECT_OPTIONS "${ESPTOOLPY_FLASH_OPTIONS}")
set(ESPTOOLPY_FLASH_PROJECT_OPTIONS
"${ESPTOOLPY_FLASH_PROJECT_OPTIONS}"
APP_BIN_UNSIGNED ?= $(APP_BIN)
$(APP_BIN_UNSIGNED): $(APP_ELF) $(ESPTOOLPY_SRC) | check_python_dependencies
+ifeq ("$(CONFIG_APP_BUILD_GENERATE_BINARIES)","y")
$(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $<
+else
+ @echo "Skipping the BIN generation"
+endif
ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
encrypted-flash: all_binaries $(ESPTOOLPY_SRC) $(call prereq_if_explicit,erase_flash) partition_table_get_info | check_python_dependencies
#
# Add 'app.bin' target - generates with elf2image
#
-add_custom_command(OUTPUT "${build_dir}/.bin_timestamp"
- COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_FLASH_OPTIONS} ${ESPTOOLPY_ELF2IMAGE_OPTIONS}
- -o "${build_dir}/${unsigned_project_binary}" "${elf}"
- COMMAND ${CMAKE_COMMAND} -E echo "Generated ${build_dir}/${unsigned_project_binary}"
- COMMAND ${CMAKE_COMMAND} -E md5sum "${build_dir}/${unsigned_project_binary}" > "${build_dir}/.bin_timestamp"
- DEPENDS ${elf}
- VERBATIM
- WORKING_DIRECTORY ${build_dir}
- COMMENT "Generating binary image from built executable"
- )
-add_custom_target(gen_project_binary DEPENDS "${build_dir}/.bin_timestamp")
+if(CONFIG_APP_BUILD_GENERATE_BINARIES)
+ add_custom_command(OUTPUT "${build_dir}/.bin_timestamp"
+ COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_FLASH_OPTIONS} ${ESPTOOLPY_ELF2IMAGE_OPTIONS}
+ -o "${build_dir}/${unsigned_project_binary}" "${elf}"
+ COMMAND ${CMAKE_COMMAND} -E echo "Generated ${build_dir}/${unsigned_project_binary}"
+ COMMAND ${CMAKE_COMMAND} -E md5sum "${build_dir}/${unsigned_project_binary}" > "${build_dir}/.bin_timestamp"
+ DEPENDS ${elf}
+ VERBATIM
+ WORKING_DIRECTORY ${build_dir}
+ COMMENT "Generating binary image from built executable"
+ )
+ add_custom_target(gen_project_binary DEPENDS "${build_dir}/.bin_timestamp")
+endif()
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
"${build_dir}/${unsigned_project_binary}"
)
-add_custom_target(app ALL DEPENDS gen_project_binary)
+if(CONFIG_APP_BUILD_GENERATE_BINARIES)
+ add_custom_target(app ALL DEPENDS gen_project_binary)
+endif()
if(NOT BOOTLOADER_BUILD AND CONFIG_SECURE_SIGNED_APPS)
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
These variables have the start and end of the data and static IRAM
area used by the program. Defined in the linker script.
*/
-extern int _data_start, _static_data_end, _iram_start, _iram_end;
+extern int _data_start, _heap_start, _iram_start, _iram_end;
/* static DRAM & IRAM chunks */
static const size_t EXTRA_RESERVED_REGIONS = 2;
(count - EXTRA_RESERVED_REGIONS) * sizeof(soc_reserved_region_t));
/* Add the EXTRA_RESERVED_REGIONS at the beginning */
- reserved[0].start = (intptr_t)&_data_start; /* DRAM used by data+bss */
- reserved[0].end = (intptr_t)&_static_data_end;
+ reserved[0].start = (intptr_t)&_data_start; /* DRAM used by data+bss and possibly rodata */
+ reserved[0].end = (intptr_t)&_heap_start;
reserved[1].start = (intptr_t)&_iram_start; /* IRAM used by code */
reserved[1].end = (intptr_t)&_iram_end;
--- /dev/null
+# Connect to a running instance of OpenOCD
+target remote 127.0.0.1:3333
+# Reset and halt the target
+mon reset halt
+# Run to a specific point in ROM code,
+# where most of initialization is complete.
+thb *0x40007901
+c
+# Load the application into RAM
+load
+# Run till app_main
+tb app_main
+c
--- /dev/null
+import os
+import pexpect
+import serial
+import sys
+import threading
+import time
+
+try:
+ import IDF
+except ImportError:
+ test_fw_path = os.getenv('TEST_FW_PATH')
+ if test_fw_path and test_fw_path not in sys.path:
+ sys.path.insert(0, test_fw_path)
+ import IDF
+
+import Utility
+
+
+class CustomProcess(object):
+ def __init__(self, cmd, logfile):
+ self.f = open(logfile, 'wb')
+ self.p = pexpect.spawn(cmd, timeout=60, logfile=self.f)
+
+ def __enter__(self):
+ return self
+
+ def close(self):
+ self.p.terminate(force=True)
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+ self.f.close()
+
+
+class OCDProcess(CustomProcess):
+ def __init__(self, proj_path):
+ cmd = 'openocd -f interface/ftdi/esp32_devkitj_v1.cfg -f board/esp-wroom-32.cfg'
+ log_file = os.path.join(proj_path, 'openocd.log')
+ super(OCDProcess, self).__init__(cmd, log_file)
+ i = self.p.expect_exact(['Info : Listening on port 3333 for gdb connections', 'Error:'])
+ if i == 0:
+ Utility.console_log('openocd is listening for gdb connections')
+ else:
+ raise RuntimeError('openocd initialization has failed')
+
+ def close(self):
+ try:
+ self.p.sendcontrol('c')
+ self.p.expect_exact('shutdown command invoked')
+ except Exception:
+ Utility.console_log('openocd needs to be killed', 'O')
+ super(OCDProcess, self).close()
+
+
+class GDBProcess(CustomProcess):
+ def __init__(self, proj_path, elf_path):
+ cmd = 'xtensa-esp32-elf-gdb -x {} --directory={} {}'.format(os.path.join(proj_path, '.gdbinit.ci'),
+ os.path.join(proj_path, 'main'),
+ elf_path)
+ log_file = os.path.join(proj_path, 'gdb.log')
+ super(GDBProcess, self).__init__(cmd, log_file)
+ self.p.sendline('') # it is for "---Type <return> to continue, or q <return> to quit---"
+ i = self.p.expect_exact(['Thread 1 hit Temporary breakpoint 2, app_main ()',
+ 'Load failed'])
+ if i == 0:
+ Utility.console_log('gdb is at breakpoint')
+ else:
+ raise RuntimeError('Load failed: probably the ELF file was not built for loading with gdb')
+ self.p.expect_exact('(gdb)')
+
+ def close(self):
+ try:
+ self.p.sendline('q')
+ self.p.expect_exact('Quit anyway? (y or n)')
+ self.p.sendline('y')
+ self.p.expect_exact('Ending remote debugging.')
+ except Exception:
+ Utility.console_log('gdb needs to be killed', 'O')
+ super(GDBProcess, self).close()
+
+ def break_till_end(self):
+ self.p.sendline('b esp_restart')
+ self.p.sendline('c')
+ self.p.expect_exact('Thread 1 hit Breakpoint 3, esp_restart ()')
+
+
+class SerialThread(object):
+ def run(self, log_path, exit_event):
+ with serial.Serial('/dev/ttyUSB1', 115200) as ser, open(log_path, 'wb') as f:
+ while True:
+ f.write(ser.read(ser.in_waiting))
+ if exit_event.is_set():
+ break
+ time.sleep(1)
+
+ def __init__(self, log_path):
+ self.exit_event = threading.Event()
+ self.t = threading.Thread(target=self.run, args=(log_path, self.exit_event,))
+ self.t.start()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.exit_event.set()
+ self.t.join(60)
+ if self.t.is_alive():
+ Utility.console_log('The pyserial thread is still alive', 'O')
+
+
+@IDF.idf_example_test(env_tag="test_jtag_arm")
+def test_examples_loadable_elf(env, extra_data):
+
+ idf_path = os.environ['IDF_PATH']
+ rel_project_path = os.path.join('examples', 'get-started', 'hello_world')
+ proj_path = os.path.join(idf_path, rel_project_path)
+ elf_path = os.path.join(IDF.Example(rel_project_path).get_binary_path(rel_project_path), 'hello-world.elf')
+ esp_log_path = os.path.join(proj_path, 'esp.log')
+
+ with SerialThread(esp_log_path):
+ with OCDProcess(proj_path), GDBProcess(proj_path, elf_path) as gdb:
+ gdb.break_till_end()
+
+ if pexpect.run('grep "Restarting now." {}'.format(esp_log_path), withexitstatus=True)[1]:
+ raise RuntimeError('Expected output from ESP was not received')
+
+
+if __name__ == '__main__':
+ test_examples_loadable_elf()
--- /dev/null
+CONFIG_APP_BUILD_TYPE_ELF_RAM=y
+CONFIG_VFS_SUPPORT_TERMIOS=
+CONFIG_NEWLIB_NANO_FORMAT=y
+CONFIG_ESP32_PANIC_PRINT_HALT=y
+CONFIG_ESP32_DEBUG_STUBS_ENABLE=
+CONFIG_ESP_ERR_TO_NAME_LOOKUP=
endif
@echo "To flash app & partition table, run 'make flash' or:"
else
+ifdef CONFIG_APP_BUILD_GENERATE_BINARIES
@echo "To flash all build output, run 'make flash' or:"
endif
+endif
+ifdef CONFIG_APP_BUILD_GENERATE_BINARIES
@echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
+else
+ @echo "Binary is not available for flashing"
+endif
# If we have `version.txt` then prefer that for extracting IDF version
$(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP)
app: $(APP_BIN) partition_table_get_info
+ifeq ("$(CONFIG_APP_BUILD_GENERATE_BINARIES)","y")
ifeq ("$(CONFIG_SECURE_BOOT_ENABLED)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image
@echo "App built but not signed. Signing step via espsecure.py:"
@echo "espsecure.py sign_data --keyfile KEYFILE $(APP_BIN)"
@echo "App built. Default flash app command is:"
@echo $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN)
endif
+else
+ @echo "Application in not built and cannot be flashed."
+endif
all_binaries: $(APP_BIN)
- ESP32
- Example_Flash_Encryption
+example_test_009:
+ extends: .example_test_template
+ tags:
+ - ESP32
+ - test_jtag_arm
+ artifacts:
+ when: always
+ paths:
+ - $CI_PROJECT_DIR/examples/get-started/hello_world/*.log
+ expire_in: 1 week
+ variables:
+ SETUP_TOOLS: "1"
+
UT_001:
extends: .unit_test_template
parallel: 50
print("Done")
return
+ if not os.path.exists(os.path.join(args.build_dir, "flasher_args.json")):
+ print("Done")
+ return
+
# Otherwise, if we built any binaries print a message about
# how to flash them
def print_flashing_message(title, key):
self.binary_path = self.get_binary_path(app_path)
self.elf_file = self._get_elf_file_path(self.binary_path)
assert os.path.exists(self.binary_path)
- if self.IDF_DOWNLOAD_CONFIG_FILE not in os.listdir(self.binary_path):
- if self.IDF_FLASH_ARGS_FILE not in os.listdir(self.binary_path):
- msg = ("Neither {} nor {} exists. "
- "Try to run 'make print_flash_cmd | tail -n 1 > {}/{}' "
- "or 'idf.py build' "
- "for resolving the issue."
- "").format(self.IDF_DOWNLOAD_CONFIG_FILE, self.IDF_FLASH_ARGS_FILE,
- self.binary_path, self.IDF_DOWNLOAD_CONFIG_FILE)
- raise AssertionError(msg)
-
- self.flash_files, self.flash_settings = self._parse_flash_download_config()
- self.partition_table = self._parse_partition_table()
+ sdkconfig_dict = self.get_sdkconfig()
+ if "CONFIG_APP_BUILD_GENERATE_BINARIES" in sdkconfig_dict:
+ # There are no flashing targets available when no binaries where generated.
+ if self.IDF_DOWNLOAD_CONFIG_FILE not in os.listdir(self.binary_path):
+ if self.IDF_FLASH_ARGS_FILE not in os.listdir(self.binary_path):
+ msg = ("Neither {} nor {} exists. "
+ "Try to run 'make print_flash_cmd | tail -n 1 > {}/{}' "
+ "or 'idf.py build' "
+ "for resolving the issue."
+ "").format(self.IDF_DOWNLOAD_CONFIG_FILE, self.IDF_FLASH_ARGS_FILE,
+ self.binary_path, self.IDF_DOWNLOAD_CONFIG_FILE)
+ raise AssertionError(msg)
+
+ self.flash_files, self.flash_settings = self._parse_flash_download_config()
+ self.partition_table = self._parse_partition_table()
@classmethod
def get_sdk_path(cls):
#endif
printf("%s", ""); /* sneakily lazy-allocate the reent structure for this test task */
+
+#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
+ /* TODO: add sufficient startup code in case of building an ELF file, so that
+ * flash cache is initialized and can work in such mode.
+ * For now this is disabled to allow running unit tests which don't require
+ * flash cache related operations.
+ */
get_test_data_partition(); /* allocate persistent partition table structures */
+#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
unity_reset_leak_checks();
test_utils_set_leak_level(CONFIG_UNITY_CRITICAL_LEAK_LEVEL_GENERAL, TYPE_LEAK_CRITICAL, COMP_LEAK_GENERAL);