From 74a04c140cc9c095d14883d6b7c79f6fde98a1d0 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 16 Jul 2024 15:35:10 +0800 Subject: [PATCH] feat(ulp): add option for routing LP-printf to HP console --- .../esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld | 9 ++++ components/ulp/Kconfig | 19 ++++++++ components/ulp/cmake/CMakeLists.txt | 2 + .../lp_core/include/ulp_lp_core_print.h | 7 +++ .../ulp/lp_core/lp_core/lp_core_print.c | 30 +++++++++++-- .../ulp/lp_core/lp_core/lp_core_startup.c | 11 ++++- .../{ => lp_core_basic_tests}/CMakeLists.txt | 2 +- .../{ => lp_core_basic_tests}/README.md | 0 .../main/CMakeLists.txt | 0 .../main/lp_core/test_main.c | 0 .../main/lp_core/test_main_counter.c | 0 .../main/lp_core/test_main_gpio.c | 0 .../main/lp_core/test_main_i2c.c | 0 .../main/lp_core/test_main_isr.c | 0 .../main/lp_core/test_main_set_timer_wakeup.c | 0 .../main/lp_core/test_main_spi_master.c | 0 .../main/lp_core/test_main_spi_slave.c | 0 .../main/lp_core/test_main_uart.c | 0 .../main/lp_core/test_shared.h | 0 .../main/test_app_main.c | 0 .../main/test_lp_core.c | 0 .../main/test_lp_core_etm.c | 0 .../main/test_lp_core_i2c.c | 0 .../main/test_lp_core_spi.c | 0 .../main/test_lp_core_uart.c | 0 .../pytest_lp_core_basic.py} | 2 +- .../sdkconfig.ci.default | 0 .../sdkconfig.defaults | 0 .../lp_core/lp_core_hp_uart/CMakeLists.txt | 14 ++++++ .../lp_core/lp_core_hp_uart/README.md | 3 ++ .../lp_core_hp_uart/main/CMakeLists.txt | 11 +++++ .../main/lp_core/test_hello_main.c | 16 +++++++ .../lp_core_hp_uart/main/test_app_main.c | 41 ++++++++++++++++++ .../lp_core_hp_uart/main/test_lp_core.c | 43 +++++++++++++++++++ .../lp_core_hp_uart/pytest_lp_core_hp_uart.py | 14 ++++++ .../lp_core_hp_uart/sdkconfig.ci.default | 0 .../lp_core_hp_uart/sdkconfig.defaults | 7 +++ docs/en/api-reference/system/ulp-lp-core.rst | 2 + 38 files changed, 226 insertions(+), 7 deletions(-) create mode 100644 components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/CMakeLists.txt (94%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/README.md (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/CMakeLists.txt (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_counter.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_gpio.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_i2c.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_isr.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_set_timer_wakeup.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_spi_master.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_spi_slave.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_main_uart.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/lp_core/test_shared.h (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/test_app_main.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/test_lp_core.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/test_lp_core_etm.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/test_lp_core_i2c.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/test_lp_core_spi.c (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/main/test_lp_core_uart.c (100%) rename components/ulp/test_apps/lp_core/{pytest_lp_core.py => lp_core_basic_tests/pytest_lp_core_basic.py} (91%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/sdkconfig.ci.default (100%) rename components/ulp/test_apps/lp_core/{ => lp_core_basic_tests}/sdkconfig.defaults (100%) create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.ci.default create mode 100644 components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults diff --git a/components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld b/components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld new file mode 100644 index 0000000000..4d7fc793e2 --- /dev/null +++ b/components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** ROM APIs + */ + +PROVIDE ( esp_rom_output_putc = uart_tx_one_char ); diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index 94167bd5df..53be58f829 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -106,6 +106,25 @@ menu "Ultra Low Power (ULP) Co-processor" Disabling this option will reduce the LP core binary size by not linking in panic handler functionality. + config ULP_HP_UART_CONSOLE_PRINT + depends on ULP_COPROC_TYPE_LP_CORE + bool + prompt "Route lp_core_printf to the console HP-UART" + help + Set this option to route lp_core_printf to the console HP-UART. + This allows you to easily view print outputs from the LP core, without + having to connect to the LP-UART. This option comes with the following + limitations: + + 1. There is no mutual exclusion between the HP-Core and the LP-Core accessing + the HP-UART, which means that if both cores are logging heavily the output + strings might get mangled together. + 2. The HP-UART can only work while the HP-Core is running, which means that + if the HP-Core is in deep sleep, the LP-Core will not be able to print to the + console HP-UART. + + Due to these limitations it is only recommended to use this option for easy debugging. + For more serious use-cases you should use the LP-UART. endmenu endmenu # Ultra Low Power (ULP) Co-processor diff --git a/components/ulp/cmake/CMakeLists.txt b/components/ulp/cmake/CMakeLists.txt index 0664238e4c..20db7cdb3f 100644 --- a/components/ulp/cmake/CMakeLists.txt +++ b/components/ulp/cmake/CMakeLists.txt @@ -135,6 +135,8 @@ elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) PRIVATE SHELL:-T ${IDF_PATH}/components/esp_rom/${IDF_TARGET}/ld/${IDF_TARGET}lp.rom.newlib.ld) target_link_options(${ULP_APP_NAME} PRIVATE SHELL:-T ${IDF_PATH}/components/esp_rom/${IDF_TARGET}/ld/${IDF_TARGET}lp.rom.version.ld) + target_link_options(${ULP_APP_NAME} + PRIVATE SHELL:-T ${IDF_PATH}/components/esp_rom/${IDF_TARGET}/ld/${IDF_TARGET}lp.rom.api.ld) endif() target_sources(${ULP_APP_NAME} PRIVATE ${ULP_S_SOURCES}) diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h index 6544ba7201..27a080581d 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h @@ -37,3 +37,10 @@ void lp_core_printf(const char* format, ...); extern void ets_install_uart_printf(void); #define lp_core_install_uart_print ets_install_uart_printf #endif /* CONFIG_ULP_ROM_PRINT_ENABLE */ + +/** + * @brief Print a single character from the LP core + * + * @param c character to be printed + */ +void lp_core_print_char(char c); diff --git a/components/ulp/lp_core/lp_core/lp_core_print.c b/components/ulp/lp_core/lp_core/lp_core_print.c index a14a91bcc6..0a704c28a3 100644 --- a/components/ulp/lp_core/lp_core/lp_core_print.c +++ b/components/ulp/lp_core/lp_core/lp_core_print.c @@ -6,25 +6,47 @@ #include #include "sdkconfig.h" #include "ulp_lp_core_uart.h" - -#if !CONFIG_ULP_ROM_PRINT_ENABLE +#include "hal/uart_hal.h" +#include "esp_rom_uart.h" #define LP_UART_PORT_NUM LP_UART_NUM_0 #define BINARY_SUPPORT 1 #define is_digit(c) ((c >= '0') && (c <= '9')) +#if CONFIG_ULP_HP_UART_CONSOLE_PRINT +void __attribute__((alias("hp_uart_send_char"))) lp_core_print_char(char c); + +static void hp_uart_send_char(char t) +{ + uart_dev_t *uart = (uart_dev_t *)UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM); + + while (uart_ll_get_txfifo_len(uart) < 2) { + ; + } + uart_ll_write_txfifo(uart, &t, 1); +} +#elif !CONFIG_ULP_ROM_PRINT_ENABLE +void __attribute__((alias("lp_uart_send_char"))) lp_core_print_char(char c); static void lp_uart_send_char(char c) { int tx_len = 0; int loop_cnt = 0; - /* Write one byte to LP UART. Break after few iterations if we are stuck for any reason. */ while (tx_len != 1 && loop_cnt < 1000) { tx_len = lp_core_uart_tx_chars(LP_UART_PORT_NUM, (const void *)&c, 1); loop_cnt++; } } +#else +void __attribute__((alias("lp_rom_send_char"))) lp_core_print_char(char c); +static void lp_rom_send_char(char c) +{ + esp_rom_output_putc(c); +} +#endif // CONFIG_ULP_HP_UART_CONSOLE_PRINT + +#if !CONFIG_ULP_ROM_PRINT_ENABLE // Ported over ROM function _cvt() static int lp_core_cvt(unsigned long long val, char *buf, long radix, char *digits) @@ -268,7 +290,7 @@ int lp_core_printf(const char* format, ...) va_start(ap, format); /* Pass the input string and the argument list to ets_vprintf() */ - int ret = lp_core_ets_vprintf(lp_uart_send_char, format, ap); + int ret = lp_core_ets_vprintf(lp_core_print_char, format, ap); va_end(ap); diff --git a/components/ulp/lp_core/lp_core/lp_core_startup.c b/components/ulp/lp_core/lp_core/lp_core_startup.c index 4d87b07fd1..81cd5c91bc 100644 --- a/components/ulp/lp_core/lp_core/lp_core_startup.c +++ b/components/ulp/lp_core/lp_core/lp_core_startup.c @@ -1,18 +1,27 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" #include "soc/soc_caps.h" +#include "esp_rom_caps.h" +#include "rom/ets_sys.h" #include "ulp_lp_core_utils.h" #include "ulp_lp_core_lp_timer_shared.h" #include "ulp_lp_core_memory_shared.h" +#include "ulp_lp_core_print.h" extern void main(); /* Initialize lp core related system functions before calling user's main*/ void lp_core_startup() { + +#if CONFIG_ULP_HP_UART_CONSOLE_PRINT && ESP_ROM_HAS_LP_ROM + ets_install_putc1(lp_core_print_char); +#endif + ulp_lp_core_update_wakeup_cause(); main(); diff --git a/components/ulp/test_apps/lp_core/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/CMakeLists.txt similarity index 94% rename from components/ulp/test_apps/lp_core/CMakeLists.txt rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/CMakeLists.txt index 5a16c97e49..2881fcd2f4 100644 --- a/components/ulp/test_apps/lp_core/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/CMakeLists.txt @@ -11,4 +11,4 @@ set(EXTRA_COMPONENT_DIRS set(COMPONENTS main) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(lp_core_test) +project(lp_core_basic_tests) diff --git a/components/ulp/test_apps/lp_core/README.md b/components/ulp/test_apps/lp_core/lp_core_basic_tests/README.md similarity index 100% rename from components/ulp/test_apps/lp_core/README.md rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/README.md diff --git a/components/ulp/test_apps/lp_core/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt similarity index 100% rename from components/ulp/test_apps/lp_core/main/CMakeLists.txt rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_counter.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_counter.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_counter.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_counter.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_gpio.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_gpio.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_gpio.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_gpio.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_i2c.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_i2c.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_i2c.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_i2c.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_isr.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_isr.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_isr.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_isr.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_set_timer_wakeup.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_set_timer_wakeup.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_set_timer_wakeup.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_set_timer_wakeup.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_master.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_master.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_master.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_master.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_slave.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_slave.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_spi_slave.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_slave.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_uart.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_uart.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_uart.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_uart.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_shared.h similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_shared.h rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_shared.h diff --git a/components/ulp/test_apps/lp_core/main/test_app_main.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_app_main.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_app_main.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_app_main.c diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_lp_core.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core_etm.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_etm.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_lp_core_etm.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_etm.c diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core_i2c.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_i2c.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_lp_core_i2c.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_i2c.c diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core_spi.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_spi.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_lp_core_spi.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_spi.c diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core_uart.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_uart.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_lp_core_uart.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_uart.c diff --git a/components/ulp/test_apps/lp_core/pytest_lp_core.py b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py similarity index 91% rename from components/ulp/test_apps/lp_core/pytest_lp_core.py rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py index 0c8a36668c..325bd2ca59 100644 --- a/components/ulp/test_apps/lp_core/pytest_lp_core.py +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut diff --git a/components/ulp/test_apps/lp_core/sdkconfig.ci.default b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.default similarity index 100% rename from components/ulp/test_apps/lp_core/sdkconfig.ci.default rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.default diff --git a/components/ulp/test_apps/lp_core/sdkconfig.defaults b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults similarity index 100% rename from components/ulp/test_apps/lp_core/sdkconfig.defaults rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt new file mode 100644 index 0000000000..2c8bfb9861 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt @@ -0,0 +1,14 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults") + +set(EXTRA_COMPONENT_DIRS + "$ENV{IDF_PATH}/tools/unit-test-app/components" +) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(lp_core_hp_uart_test) diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md b/components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md new file mode 100644 index 0000000000..59db987a22 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md @@ -0,0 +1,3 @@ +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | + diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt new file mode 100644 index 0000000000..6fce89dfdd --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(app_sources "test_app_main.c" "test_lp_core.c") +set(lp_core_sources "lp_core/test_hello_main.c") + +idf_component_register(SRCS ${app_sources} + INCLUDE_DIRS "lp_core" + REQUIRES ulp unity esp_timer test_utils + WHOLE_ARCHIVE) + +set(lp_core_exp_dep_srcs ${app_sources}) + +ulp_embed_binary(lp_core_test_app "${lp_core_sources}" "${lp_core_exp_dep_srcs}") diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c new file mode 100644 index 0000000000..3c844cec7d --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "ulp_lp_core_print.h" + +int main(void) +{ + lp_core_printf("Hello, World!\n"); + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c new file mode 100644 index 0000000000..d8a9a98ccc --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in the sleep code, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-500) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c new file mode 100644 index 0000000000..0d3949cd59 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "sdkconfig.h" +#include "unity.h" +#include "soc/soc_caps.h" +#include "esp_rom_caps.h" +#include "lp_core_test_app.h" +#include "ulp_lp_core.h" + +extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start"); +extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end"); + +static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) +{ + TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, + (firmware_end - firmware_start)) == ESP_OK); + + TEST_ASSERT(ulp_lp_core_run(cfg) == ESP_OK); + +} + +TEST_CASE("lp-print can output to hp-uart", "[lp_core]") +{ + /* Load ULP firmware and start the coprocessor */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + load_and_start_lp_core_firmware(&cfg, lp_core_main_bin_start, lp_core_main_bin_end); + + // Actual test output on UART is checked by pytest, not unity test-case + // We simply wait to allow the lp-core to run once + vTaskDelay(1000 / portTICK_PERIOD_MS); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py new file mode 100644 index 0000000000..df0edfec74 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32c5 +@pytest.mark.esp32c6 +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_lp_core_hp_uart_print(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('"lp-print can output to hp-uart"') + dut.expect_exact('Hello, World!') diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.ci.default b/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.ci.default new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults b/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults new file mode 100644 index 0000000000..e3c08c60fa --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults @@ -0,0 +1,7 @@ +CONFIG_ESP_TASK_WDT_INIT=n + +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=12000 +CONFIG_ULP_PANIC_OUTPUT_ENABLE=y +CONFIG_ULP_HP_UART_CONSOLE_PRINT=y diff --git a/docs/en/api-reference/system/ulp-lp-core.rst b/docs/en/api-reference/system/ulp-lp-core.rst index ec5bfa083e..dd3cb7cd0c 100644 --- a/docs/en/api-reference/system/ulp-lp-core.rst +++ b/docs/en/api-reference/system/ulp-lp-core.rst @@ -212,6 +212,8 @@ When programming the LP-Core, it can sometimes be challenging to figure out why * Use the LP-UART to print: the LP-Core has access to the LP-UART peripheral, which can be used for printing information independently of the main CPU sleep state. See :example:`system/ulp/lp_core/lp_uart/lp_uart_print` for an example of how to use this driver. +* Routing :cpp:func:`lp_core_printf` to the HP-Core console UART with :ref:`CONFIG_ULP_HP_UART_CONSOLE_PRINT`. This allows you to easily print LP-Core information to the already connected HP-Core console UART. The drawback of this approach is that it requires the main CPU to be awake and since there is no synchronization between the LP and HP cores, the output may be interleaved. + * Share program state through shared variables: as described in :ref:`ulp-lp-core-access-variables`, both the main CPU and the ULP core can easily access global variables in RTC memory. Writing state information to such a variable from the ULP and reading it from the main CPU can help you discern what is happening on the ULP core. The downside of this approach is that it requires the main CPU to be awake, which will not always be the case. Keeping the main CPU awake might even, in some cases, mask problems, as some issues may only occur when certain power domains are powered down. * Panic handler: the LP-Core has a panic handler that can dump the state of the LP-Core registers by the LP-UART when an exception is detected. To enable the panic handler, set the :ref:`CONFIG_ULP_PANIC_OUTPUT_ENABLE` option to ``y``. This option can be kept disabled to reduce LP-RAM usage by the LP-Core application. To recover a backtrace from the panic dump, it is possible to use esp-idf-monitor_., e.g.: