From 42a6b47aa883dbcbb1fe91126d147e67829050d0 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Fri, 31 Mar 2023 19:25:46 +0800 Subject: [PATCH 1/6] hal: Adds cache hal --- components/hal/esp32/include/hal/cache_ll.h | 95 +++++++++++++++++++ components/hal/esp32s3/include/hal/cache_ll.h | 84 ++++++++++++++++ components/hal/include/hal/cache_types.h | 33 +++++++ 3 files changed, 212 insertions(+) create mode 100644 components/hal/esp32/include/hal/cache_ll.h create mode 100644 components/hal/esp32s3/include/hal/cache_ll.h create mode 100644 components/hal/include/hal/cache_types.h diff --git a/components/hal/esp32/include/hal/cache_ll.h b/components/hal/esp32/include/hal/cache_ll.h new file mode 100644 index 0000000000..7157eff9c5 --- /dev/null +++ b/components/hal/esp32/include/hal/cache_ll.h @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for Cache register operations + +#pragma once + +#include +#include "soc/dport_reg.h" +#include "hal/cache_types.h" +#include "hal/assert.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Enable the Cache Buses + * + * @param cache_id cache ID (when l1 cache is per core) + * @param mask To know which buses should be enabled + * @param enable 1: enable; 0: disable + */ +#if !BOOTLOADER_BUILD +__attribute__((always_inline)) +#endif +static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t mask) +{ + (void) mask; + HAL_ASSERT(cache_id == 0 || cache_id == 1); + + uint32_t bus_mask = 0; + if (cache_id == 0) { + bus_mask |= (mask & CACHE_BUS_IBUS0) ? DPORT_PRO_CACHE_MASK_IRAM0 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS1) ? DPORT_PRO_CACHE_MASK_IRAM1 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS2) ? DPORT_PRO_CACHE_MASK_IROM0 : 0; + + bus_mask |= (mask & CACHE_BUS_DBUS0) ? DPORT_PRO_CACHE_MASK_DROM0 : 0; + bus_mask |= (mask & CACHE_BUS_DBUS1) ? DPORT_PRO_CACHE_MASK_DRAM1 : 0; + + DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, bus_mask); + } else { + bus_mask |= (mask & CACHE_BUS_IBUS0) ? DPORT_APP_CACHE_MASK_IRAM0 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS1) ? DPORT_APP_CACHE_MASK_IRAM1 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS2) ? DPORT_APP_CACHE_MASK_IROM0 : 0; + + bus_mask |= (mask & CACHE_BUS_DBUS0) ? DPORT_APP_CACHE_MASK_DROM0 : 0; + bus_mask |= (mask & CACHE_BUS_DBUS1) ? DPORT_APP_CACHE_MASK_DRAM1 : 0; + + DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, bus_mask); + } +} + +/** + * Disable the Cache Buses + * + * @param cache_id cache ID (when l1 cache is per core) + * @param mask To know which buses should be enabled + * @param enable 1: enable; 0: disable + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t mask) +{ + (void) mask; + HAL_ASSERT(cache_id == 0 || cache_id == 1); + + uint32_t bus_mask = 0; + if (cache_id == 0) { + bus_mask |= (mask & CACHE_BUS_IBUS0) ? DPORT_PRO_CACHE_MASK_IRAM0 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS1) ? DPORT_PRO_CACHE_MASK_IRAM1 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS2) ? DPORT_PRO_CACHE_MASK_IROM0 : 0; + + bus_mask |= (mask & CACHE_BUS_DBUS0) ? DPORT_PRO_CACHE_MASK_DROM0 : 0; + bus_mask |= (mask & CACHE_BUS_DBUS1) ? DPORT_PRO_CACHE_MASK_DRAM1 : 0; + + DPORT_REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, bus_mask); + } else { + bus_mask |= (mask & CACHE_BUS_IBUS0) ? DPORT_APP_CACHE_MASK_IRAM0 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS1) ? DPORT_APP_CACHE_MASK_IRAM1 : 0; + bus_mask |= (mask & CACHE_BUS_IBUS2) ? DPORT_APP_CACHE_MASK_IROM0 : 0; + + bus_mask |= (mask & CACHE_BUS_DBUS0) ? DPORT_APP_CACHE_MASK_DROM0 : 0; + bus_mask |= (mask & CACHE_BUS_DBUS1) ? DPORT_APP_CACHE_MASK_DRAM1 : 0; + + DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, bus_mask); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/include/hal/cache_ll.h b/components/hal/esp32s3/include/hal/cache_ll.h new file mode 100644 index 0000000000..c4de594de1 --- /dev/null +++ b/components/hal/esp32s3/include/hal/cache_ll.h @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for Cache register operations + +#pragma once + +#include "soc/extmem_reg.h" +#include "hal/cache_types.h" +#include "hal/assert.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Enable the Cache Buses + * + * @param cache_id cache ID (when l1 cache is per core) + * @param mask To know which buses should be enabled + */ +#if !BOOTLOADER_BUILD +__attribute__((always_inline)) +#endif +static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t mask) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + //On esp32s3, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first + HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2| CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0); + + uint32_t ibus_mask = 0; + if (cache_id == 0) { + ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_ICACHE_SHUT_CORE0_BUS : 0; + } else { + ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_ICACHE_SHUT_CORE1_BUS : 0; + } + REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, ibus_mask); + + uint32_t dbus_mask = 0; + if (cache_id == 1) { + dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_CORE0_BUS : 0; + } else { + dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_CORE1_BUS : 0; + } + REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, dbus_mask); +} + +/** + * Disable the Cache Buses + * + * @param cache_id cache ID (when l1 cache is per core) + * @param mask To know which buses should be disabled + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t mask) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + //On esp32s3, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first + HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2| CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0); + + uint32_t ibus_mask = 0; + if (cache_id == 0) { + ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_ICACHE_SHUT_CORE0_BUS : 0; + } else { + ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_ICACHE_SHUT_CORE1_BUS : 0; + } + REG_SET_BIT(EXTMEM_ICACHE_CTRL1_REG, ibus_mask); + + uint32_t dbus_mask = 0; + if (cache_id == 1) { + dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_CORE0_BUS : 0; + } else { + dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_CORE1_BUS : 0; + } + REG_SET_BIT(EXTMEM_DCACHE_CTRL1_REG, dbus_mask); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/cache_types.h b/components/hal/include/hal/cache_types.h new file mode 100644 index 0000000000..0a7cee8fe8 --- /dev/null +++ b/components/hal/include/hal/cache_types.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Ibuses and Dbuses. + * + * @note + * These enumurations are abstract concepts. Virtual address reside in one of these buses. + * Therefore, use `cache_ll_l1_get_bus(cache_id, vaddr_start, len)` to convert your vaddr into buses first + */ +typedef enum { + CACHE_BUS_IBUS0 = BIT(0), + CACHE_BUS_IBUS1 = BIT(1), + CACHE_BUS_IBUS2 = BIT(2), + CACHE_BUS_DBUS0 = BIT(3), + CACHE_BUS_DBUS1 = BIT(4), + CACHE_BUS_DBUS2 = BIT(5), +} cache_bus_mask_t; + +#ifdef __cplusplus +} +#endif From 1b608a1c0757529c54b701961f97fd17195f6149 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Fri, 31 Mar 2023 19:46:27 +0800 Subject: [PATCH 2/6] esp_system: Do not rely on bootloader cache settings, do cache settings unconditionally at startup app It makes multicore app runnable by unicore bootloader Closes https://github.com/espressif/esp-idf/issues/10714 --- .../bootloader_support/src/bootloader_init.c | 8 ++++ components/esp_system/port/cpu_start.c | 45 +++++++++++++++++++ components/hal/esp32/include/hal/cache_ll.h | 32 +++++++++++++ components/hal/esp32s3/include/hal/cache_ll.h | 31 +++++++++++++ 4 files changed, 116 insertions(+) diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 932cac265c..3fc18415d7 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -94,4 +94,12 @@ void bootloader_print_banner(void) { ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER); ESP_LOGI(TAG, "compile time " __TIME__); + +#if CONFIG_FREERTOS_UNICORE +#if (SOC_CPU_CORES_NUM > 1) + ESP_EARLY_LOGW(TAG, "Unicore bootloader"); +#endif +#else + ESP_EARLY_LOGI(TAG, "Multicore bootloader"); +#endif } diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 913bfb6144..f2c18f7237 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -70,6 +70,10 @@ #include "hal/wdt_hal.h" #include "soc/rtc.h" #include "soc/efuse_reg.h" +#if (SOC_CPU_CORES_NUM > 1) +#include "hal/cache_ll.h" +#endif +#include "hal/efuse_ll.h" #include "soc/periph_defs.h" #include "soc/cpu.h" #include "soc/rtc.h" @@ -244,6 +248,39 @@ static void start_other_core(void) esp_rom_delay_us(100); } } + +// This function is needed to make the multicore app runnable on a unicore bootloader (built with FREERTOS UNICORE). +// It does some cache settings for other CPUs. +void IRAM_ATTR do_multicore_settings(void) +{ + // We intentionally do not check the cache settings before changing them, + // because it helps to get the application to run on older bootloaders. +#ifdef CONFIG_IDF_TARGET_ESP32 + if (!efuse_ll_get_disable_app_cpu()) { + Cache_Read_Disable(1); + Cache_Flush(1); + DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); + DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); + // We do not enable cache for CPU1 now because it will be done later in start_other_core(). + } +#endif + + cache_bus_mask_t cache_bus_mask_core0 = cache_ll_l1_get_enabled_bus(0); +#ifndef CONFIG_IDF_TARGET_ESP32 + // 1. disable the cache before changing its settings. + Cache_Disable_ICache(); + Cache_Disable_DCache(); +#endif + for (unsigned core = 1; core < SOC_CPU_CORES_NUM; core++) { + // 2. change cache settings. All cores must have the same settings. + cache_ll_l1_enable_bus(core, cache_bus_mask_core0); + } +#ifndef CONFIG_IDF_TARGET_ESP32 + // 3. enable the cache after changing its settings. + Cache_Enable_ICache(0); + Cache_Enable_DCache(0); +#endif +} #endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE /* @@ -312,6 +349,14 @@ void IRAM_ATTR call_start_cpu0(void) memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start)); } +#if CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + ESP_EARLY_LOGI(TAG, "Unicore app"); +#else + ESP_EARLY_LOGI(TAG, "Multicore app"); + // It helps to fix missed cache settings for other cores. It happens when bootloader is unicore. + do_multicore_settings(); +#endif + #if CONFIG_IDF_TARGET_ESP32S2 /* Configure the mode of instruction cache : cache size, cache associated ways, cache line size. */ extern void esp_config_instruction_cache_mode(void); diff --git a/components/hal/esp32/include/hal/cache_ll.h b/components/hal/esp32/include/hal/cache_ll.h index 7157eff9c5..ec7dd87d94 100644 --- a/components/hal/esp32/include/hal/cache_ll.h +++ b/components/hal/esp32/include/hal/cache_ll.h @@ -55,6 +55,38 @@ static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t ma } } +/** + * Returns enabled buses for a given core + * + * @param cache_id cache ID (when l1 cache is per core) + * + * @return State of enabled buses + */ +__attribute__((always_inline)) +static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id) +{ + cache_bus_mask_t mask = 0; + HAL_ASSERT(cache_id == 0 || cache_id == 1); + if (cache_id == 0) { + uint32_t bus_mask= DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG); + mask |= (!(bus_mask & DPORT_PRO_CACHE_MASK_IRAM0)) ? CACHE_BUS_IBUS0 : 0; + mask |= (!(bus_mask & DPORT_PRO_CACHE_MASK_IRAM1)) ? CACHE_BUS_IBUS1 : 0; + mask |= (!(bus_mask & DPORT_PRO_CACHE_MASK_IROM0)) ? CACHE_BUS_IBUS2 : 0; + + mask |= (!(bus_mask & DPORT_PRO_CACHE_MASK_DROM0)) ? CACHE_BUS_DBUS0 : 0; + mask |= (!(bus_mask & DPORT_PRO_CACHE_MASK_DRAM1)) ? CACHE_BUS_DBUS1 : 0; + } else { + uint32_t bus_mask= DPORT_REG_READ(DPORT_APP_CACHE_CTRL1_REG); + mask |= (!(bus_mask & DPORT_APP_CACHE_MASK_IRAM0)) ? CACHE_BUS_IBUS0 : 0; + mask |= (!(bus_mask & DPORT_APP_CACHE_MASK_IRAM1)) ? CACHE_BUS_IBUS1 : 0; + mask |= (!(bus_mask & DPORT_APP_CACHE_MASK_IROM0)) ? CACHE_BUS_IBUS2 : 0; + + mask |= (!(bus_mask & DPORT_APP_CACHE_MASK_DROM0)) ? CACHE_BUS_DBUS0 : 0; + mask |= (!(bus_mask & DPORT_APP_CACHE_MASK_DRAM1)) ? CACHE_BUS_DBUS1 : 0; + } + return mask; +} + /** * Disable the Cache Buses * diff --git a/components/hal/esp32s3/include/hal/cache_ll.h b/components/hal/esp32s3/include/hal/cache_ll.h index c4de594de1..58125d0a3f 100644 --- a/components/hal/esp32s3/include/hal/cache_ll.h +++ b/components/hal/esp32s3/include/hal/cache_ll.h @@ -49,6 +49,37 @@ static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t ma REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, dbus_mask); } +/** + * Returns enabled buses for a given core + * + * @param cache_id cache ID (when l1 cache is per core) + * + * @return State of enabled buses + */ +__attribute__((always_inline)) +static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id) +{ + cache_bus_mask_t mask = 0; + HAL_ASSERT(cache_id == 0 || cache_id == 1); + //On esp32s3, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first + + uint32_t ibus_mask = REG_READ(EXTMEM_ICACHE_CTRL1_REG); + if (cache_id == 0) { + mask |= (!(ibus_mask & EXTMEM_ICACHE_SHUT_CORE0_BUS)) ? CACHE_BUS_IBUS0 : 0; + } else { + mask |= (!(ibus_mask & EXTMEM_ICACHE_SHUT_CORE1_BUS)) ? CACHE_BUS_IBUS0 : 0; + } + + uint32_t dbus_mask = REG_READ(EXTMEM_DCACHE_CTRL1_REG); + if (cache_id == 1) { + mask |= (!(dbus_mask & EXTMEM_DCACHE_SHUT_CORE0_BUS)) ? CACHE_BUS_DBUS0 : 0; + } else { + mask |= (!(dbus_mask & EXTMEM_DCACHE_SHUT_CORE1_BUS)) ? CACHE_BUS_DBUS0 : 0; + } + + return mask; +} + /** * Disable the Cache Buses * From a2ffc9374cf14210277885fbee53bd020daf214c Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Tue, 28 Mar 2023 18:24:22 +0800 Subject: [PATCH 3/6] test_apps: Test multicore app can be run by unicore bootloader --- .../system/unicore_bootloader/CMakeLists.txt | 6 +++ .../system/unicore_bootloader/README.md | 2 + .../system/unicore_bootloader/README.txt | 4 ++ .../system/unicore_bootloader/app_test.py | 43 +++++++++++++++++++ .../unicore_bootloader/main/CMakeLists.txt | 1 + .../system/unicore_bootloader/main/main.c | 12 ++++++ .../sdkconfig.ci.multicore_cfg | 0 .../sdkconfig.ci.unicore_cfg | 1 + 8 files changed, 69 insertions(+) create mode 100644 tools/test_apps/system/unicore_bootloader/CMakeLists.txt create mode 100644 tools/test_apps/system/unicore_bootloader/README.md create mode 100644 tools/test_apps/system/unicore_bootloader/README.txt create mode 100644 tools/test_apps/system/unicore_bootloader/app_test.py create mode 100644 tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt create mode 100644 tools/test_apps/system/unicore_bootloader/main/main.c create mode 100644 tools/test_apps/system/unicore_bootloader/sdkconfig.ci.multicore_cfg create mode 100644 tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_cfg diff --git a/tools/test_apps/system/unicore_bootloader/CMakeLists.txt b/tools/test_apps/system/unicore_bootloader/CMakeLists.txt new file mode 100644 index 0000000000..4b7ab3fd72 --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_unicore_bootloader) diff --git a/tools/test_apps/system/unicore_bootloader/README.md b/tools/test_apps/system/unicore_bootloader/README.md new file mode 100644 index 0000000000..5ab630aafd --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-S3 | +| ----------------- | ----- | -------- | diff --git a/tools/test_apps/system/unicore_bootloader/README.txt b/tools/test_apps/system/unicore_bootloader/README.txt new file mode 100644 index 0000000000..875b2c9400 --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/README.txt @@ -0,0 +1,4 @@ +This project tests if the app can start up in a certain configuration. +Multicore app can start up even if the bootloader is unicore. + +The test is only for Multicore chips. diff --git a/tools/test_apps/system/unicore_bootloader/app_test.py b/tools/test_apps/system/unicore_bootloader/app_test.py new file mode 100644 index 0000000000..1ce9a2dd08 --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/app_test.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +from typing import Any + +import ttfw_idf + + +@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', group='test-apps', target=['esp32', 'esp32s3']) +def test_multicore_app_and_unicore_bootloader(env, _): # type: (Any, Any) -> None + dut = env.get_dut('unicore_bootloader', 'tools/test_apps/system/unicore_bootloader', app_config_name='multicore_cfg') + print('Using binary path: {}'.format(dut.app.binary_path)) + dut.start_app() + dut.expect('Multicore bootloader') + dut.expect('Multicore app') + dut.expect('App is running') + + another_build_path = dut.app.binary_path.replace('multicore_cfg', 'unicore_cfg') + print('Using binary from another_build_path: {}'.format(another_build_path)) + dut.bootloader_flash(another_build_path) + dut.expect('Unicore bootloader') + dut.expect('Multicore app') + dut.expect('App is running') + + +@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', group='test-apps', target=['esp32', 'esp32s3']) +def test_unicore_app_and_multicore_bootloader(env, _): # type: (Any, Any) -> None + dut = env.get_dut('unicore_bootloader', 'tools/test_apps/system/unicore_bootloader', app_config_name='unicore_cfg') + print('Using binary path: {}'.format(dut.app.binary_path)) + dut.expect('Unicore bootloader') + dut.expect('Unicore app') + dut.expect('App is running') + + another_build_path = dut.app.binary_path.replace('unicore_cfg', 'multicore_cfg') + print('Using binary from another_build_path: {}'.format(another_build_path)) + dut.bootloader_flash(another_build_path) + dut.expect('Multicore bootloader') + dut.expect('Unicore app') + dut.expect('App is running') + + +if __name__ == '__main__': + test_multicore_app_and_unicore_bootloader() + test_unicore_app_and_multicore_bootloader() diff --git a/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt b/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt new file mode 100644 index 0000000000..34613e8e3c --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt @@ -0,0 +1 @@ +idf_component_register(SRCS "main.c") diff --git a/tools/test_apps/system/unicore_bootloader/main/main.c b/tools/test_apps/system/unicore_bootloader/main/main.c new file mode 100644 index 0000000000..50c39ad016 --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/main/main.c @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +void app_main(void) +{ + printf("App is running\n"); +} diff --git a/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.multicore_cfg b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.multicore_cfg new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_cfg b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_cfg new file mode 100644 index 0000000000..f0b0b5e03d --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_cfg @@ -0,0 +1 @@ +CONFIG_FREERTOS_UNICORE=y From 20740ce0dae693aa5033ed783bf3c9bc2935b337 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Fri, 31 Mar 2023 21:19:50 +0800 Subject: [PATCH 4/6] ttfw_idf: Extend bootloader_flash API --- tools/ci/python_packages/ttfw_idf/IDFDUT.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/ci/python_packages/ttfw_idf/IDFDUT.py b/tools/ci/python_packages/ttfw_idf/IDFDUT.py index 5828eaabdb..ed5268985b 100644 --- a/tools/ci/python_packages/ttfw_idf/IDFDUT.py +++ b/tools/ci/python_packages/ttfw_idf/IDFDUT.py @@ -391,13 +391,14 @@ class IDFDUT(DUT.SerialDUT): for (_, f) in encrypt_offs_files: f.close() - def bootloader_flash(self): + def bootloader_flash(self, binary_path=None): """ download bootloader. :return: None """ - bootloader_path = os.path.join(self.app.binary_path, 'bootloader', 'bootloader.bin') + binary_path = self.app.binary_path if binary_path is None else binary_path + bootloader_path = os.path.join(binary_path, 'bootloader', 'bootloader.bin') offs = int(self.app.get_sdkconfig()['CONFIG_BOOTLOADER_OFFSET_IN_FLASH'], 0) flash_files = [(offs, bootloader_path)] self.write_flash(flash_files) From 037b70c253ca1eee8980f38f01039c6f3849d849 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Mon, 1 May 2023 15:08:23 +0800 Subject: [PATCH 5/6] ci: Increase parallel count for Example_GENERIC and ESP32S3 --- .gitlab/ci/target-test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index cb8533a04b..06b4e3d263 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -368,6 +368,12 @@ test_app_test_005: - ESP32C3 - Example_GENERIC +test_app_test_006: + extends: .test_app_esp32s3_template + tags: + - ESP32S3 + - Example_GENERIC + test_app_test_esp32_generic: extends: .test_app_esp32_template parallel: 5 From 8c11859a2f477750ea4ade7e84f72f22c80c0abb Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Mon, 1 May 2023 23:54:17 +0800 Subject: [PATCH 6/6] test_apps: Fix unicore_bootloader test --- .../system/unicore_bootloader/app_test.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tools/test_apps/system/unicore_bootloader/app_test.py b/tools/test_apps/system/unicore_bootloader/app_test.py index 1ce9a2dd08..438aa825e3 100644 --- a/tools/test_apps/system/unicore_bootloader/app_test.py +++ b/tools/test_apps/system/unicore_bootloader/app_test.py @@ -8,15 +8,14 @@ import ttfw_idf @ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', group='test-apps', target=['esp32', 'esp32s3']) def test_multicore_app_and_unicore_bootloader(env, _): # type: (Any, Any) -> None dut = env.get_dut('unicore_bootloader', 'tools/test_apps/system/unicore_bootloader', app_config_name='multicore_cfg') - print('Using binary path: {}'.format(dut.app.binary_path)) dut.start_app() dut.expect('Multicore bootloader') dut.expect('Multicore app') dut.expect('App is running') + env.close_dut(dut.name) - another_build_path = dut.app.binary_path.replace('multicore_cfg', 'unicore_cfg') - print('Using binary from another_build_path: {}'.format(another_build_path)) - dut.bootloader_flash(another_build_path) + dut = env.get_dut('unicore_bootloader', 'tools/test_apps/system/unicore_bootloader', app_config_name='unicore_cfg') + dut.bootloader_flash() dut.expect('Unicore bootloader') dut.expect('Multicore app') dut.expect('App is running') @@ -25,14 +24,14 @@ def test_multicore_app_and_unicore_bootloader(env, _): # type: (Any, Any) -> No @ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', group='test-apps', target=['esp32', 'esp32s3']) def test_unicore_app_and_multicore_bootloader(env, _): # type: (Any, Any) -> None dut = env.get_dut('unicore_bootloader', 'tools/test_apps/system/unicore_bootloader', app_config_name='unicore_cfg') - print('Using binary path: {}'.format(dut.app.binary_path)) + dut.start_app() dut.expect('Unicore bootloader') dut.expect('Unicore app') dut.expect('App is running') + env.close_dut(dut.name) - another_build_path = dut.app.binary_path.replace('unicore_cfg', 'multicore_cfg') - print('Using binary from another_build_path: {}'.format(another_build_path)) - dut.bootloader_flash(another_build_path) + dut = env.get_dut('unicore_bootloader', 'tools/test_apps/system/unicore_bootloader', app_config_name='multicore_cfg') + dut.bootloader_flash() dut.expect('Multicore bootloader') dut.expect('Unicore app') dut.expect('App is running')