ulp: added basic support for building and running a binary in the lp core

This commit is contained in:
Marius Vikhammer 2023-02-27 17:03:42 +08:00
parent daf4150846
commit 284dabf17f
33 changed files with 517 additions and 23 deletions

View File

@ -483,6 +483,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
}
#endif
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO IDF-7012 Add sleep support for lp core
#if CONFIG_ULP_COPROC_ENABLED
// Enable ULP wakeup
if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) {
@ -493,6 +494,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
#endif
}
#endif
#endif //!CONFIG_IDF_TARGET_ESP32C6
if (!deep_sleep) {
misc_modules_sleep_prepare();
@ -1000,7 +1002,7 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
}
#if CONFIG_ULP_COPROC_ENABLED
#if CONFIG_ULP_COPROC_ENABLED && !CONFIG_IDF_TARGET_ESP32C6 // TODO IDF-7012 Add sleep support for lp core
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
}

View File

@ -91,12 +91,7 @@ MEMORY
/**
* lp ram memory (RWX). Persists over deep sleep. // ESP32H2-TODO IDF-6272
*/
#if CONFIG_ULP_COPROC_ENABLED
lp_ram_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM,
len = 0x1000 - CONFIG_ULP_COPROC_RESERVE_MEM
#else
lp_ram_seg(RW) : org = 0x50000000 , len = 0x1000
#endif // CONFIG_ULP_COPROC_ENABLED
}

View File

@ -143,6 +143,10 @@ config SOC_BOD_SUPPORTED
bool
default y
config SOC_ULP_FSM_SUPPORTED
bool
default y
config SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL
int
default 5

View File

@ -95,6 +95,7 @@
#define SOC_SECURE_BOOT_SUPPORTED 1
#define SOC_TOUCH_SENSOR_SUPPORTED 1
#define SOC_BOD_SUPPORTED 1
#define SOC_ULP_FSM_SUPPORTED 1
#if SOC_CAPS_ECO_VER < 200
#define SOC_DPORT_WORKAROUND 1

View File

@ -71,6 +71,10 @@ config SOC_SUPPORTS_SECURE_DL_MODE
bool
default y
config SOC_LP_CORE_SUPPORTED
bool
default y
config SOC_EFUSE_KEY_PURPOSE_FIELD
bool
default y

View File

@ -42,7 +42,7 @@
#define SOC_TEMP_SENSOR_SUPPORTED 1
#define SOC_WIFI_SUPPORTED 1
#define SOC_SUPPORTS_SECURE_DL_MODE 1
//#define SOC_RISCV_COPROC_SUPPORTED 1 // TODO: IDF-5816
#define SOC_LP_CORE_SUPPORTED 1
#define SOC_EFUSE_KEY_PURPOSE_FIELD 1
#define SOC_RTC_FAST_MEM_SUPPORTED 1
#define SOC_RTC_MEM_SUPPORTED 1

View File

@ -40,7 +40,6 @@
#define SOC_USB_SERIAL_JTAG_SUPPORTED 1
#define SOC_TEMP_SENSOR_SUPPORTED 1
#define SOC_SUPPORTS_SECURE_DL_MODE 1
//#define SOC_RISCV_COPROC_SUPPORTED 1 // TODO: IDF-6272
#define SOC_EFUSE_KEY_PURPOSE_FIELD 1
#define SOC_RTC_FAST_MEM_SUPPORTED 1
#define SOC_RTC_MEM_SUPPORTED 1

View File

@ -35,6 +35,10 @@ config SOC_SUPPORTS_SECURE_DL_MODE
bool
default y
config SOC_ULP_FSM_SUPPORTED
bool
default y
config SOC_RISCV_COPROC_SUPPORTED
bool
default y

View File

@ -47,6 +47,7 @@
#define SOC_DEDICATED_GPIO_SUPPORTED 1
#define SOC_GPTIMER_SUPPORTED 1
#define SOC_SUPPORTS_SECURE_DL_MODE 1
#define SOC_ULP_FSM_SUPPORTED 1
#define SOC_RISCV_COPROC_SUPPORTED 1
#define SOC_USB_OTG_SUPPORTED 1
#define SOC_PCNT_SUPPORTED 1

View File

@ -71,6 +71,10 @@ config SOC_ULP_SUPPORTED
bool
default y
config SOC_ULP_FSM_SUPPORTED
bool
default y
config SOC_RISCV_COPROC_SUPPORTED
bool
default y

View File

@ -37,6 +37,7 @@
#define SOC_DEDICATED_GPIO_SUPPORTED 1
#define SOC_CACHE_SUPPORT_WRAP 1
#define SOC_ULP_SUPPORTED 1
#define SOC_ULP_FSM_SUPPORTED 1
#define SOC_RISCV_COPROC_SUPPORTED 1
#define SOC_BT_SUPPORTED 1
#define SOC_USB_OTG_SUPPORTED 1

View File

@ -1,5 +1,8 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/ulp/test_apps/lp_core:
disable:
- if: SOC_LP_CORE_SUPPORTED != 1
components/ulp/test_apps/ulp_fsm:
enable:
- if: SOC_ULP_SUPPORTED == 1

View File

@ -34,6 +34,18 @@ if(CONFIG_SOC_ULP_SUPPORTED OR CONFIG_SOC_RISCV_COPROC_SUPPORTED)
endif()
endif()
if(CONFIG_ULP_COPROC_TYPE_LP_CORE)
list(APPEND includes
ulp_common/include
ulp_common/include/${target})
list(APPEND srcs
"lp_core/lp_core.c")
list(APPEND includes
"lp_core/include")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${includes}
REQUIRES driver esp_adc)

View File

@ -1,5 +1,5 @@
menu "Ultra Low Power (ULP) Co-processor"
depends on (SOC_ULP_SUPPORTED || SOC_RISCV_COPROC_SUPPORTED)
depends on (SOC_ULP_SUPPORTED || SOC_RISCV_COPROC_SUPPORTED || SOC_LP_CORE_SUPPORTED)
config ULP_COPROC_ENABLED
bool "Enable Ultra Low Power (ULP) Co-processor"
@ -11,17 +11,19 @@ menu "Ultra Low Power (ULP) Co-processor"
choice ULP_COPROC_TYPE
prompt "ULP Co-processor type"
depends on ULP_COPROC_ENABLED
default ULP_COPROC_TYPE_FSM if IDF_TARGET_ESP32
default ULP_COPROC_TYPE_RISCV if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
help
Choose the ULP Coprocessor type: ULP FSM (Finite State Machine) or ULP RISC-V.
Please note that ESP32 only supports ULP FSM.
config ULP_COPROC_TYPE_FSM
bool "ULP FSM (Finite State Machine)"
depends on SOC_ULP_FSM_SUPPORTED
config ULP_COPROC_TYPE_RISCV
bool "ULP RISC-V"
depends on !IDF_TARGET_ESP32
depends on SOC_RISCV_COPROC_SUPPORTED
config ULP_COPROC_TYPE_LP_CORE
bool "LP core RISC-V"
depends on SOC_LP_CORE_SUPPORTED
endchoice
config ULP_COPROC_RESERVE_MEM
@ -29,8 +31,9 @@ menu "Ultra Low Power (ULP) Co-processor"
prompt "RTC slow memory reserved for coprocessor"
depends on ULP_COPROC_ENABLED
default 512 if IDF_TARGET_ESP32
default 4096 if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3)
range 32 8176
default 4096 if !IDF_TARGET_ESP32
range 32 8176 if !IDF_TARGET_ESP32C6
range 32 16352 if IDF_TARGET_ESP32C6
help
Bytes of memory to reserve for ULP Co-processor firmware & data.
Data is reserved at the beginning of RTC slow memory.

View File

@ -6,11 +6,12 @@ add_executable(${ULP_APP_NAME})
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
option(ULP_COCPU_IS_RISCV "Use RISC-V based ULP" OFF)
option(ULP_COCPU_IS_LP_CORE "Use RISC-V based LP Core" OFF)
message(STATUS "Building ULP app ${ULP_APP_NAME}")
# Check the supported assembler version
if(NOT ULP_COCPU_IS_RISCV)
if(NOT (ULP_COCPU_IS_RISCV OR ULP_COCPU_IS_LP_CORE))
check_expected_tool_version("esp32ulp-elf" ${CMAKE_ASM_COMPILER})
endif()
@ -33,9 +34,12 @@ list(APPEND ULP_PREPROCESSOR_ARGS -D__ASSEMBLER__)
# Pre-process the linker script
if(ULP_COCPU_IS_RISCV)
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_riscv.ld)
elseif(ULP_COCPU_IS_LP_CORE)
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/lp_core_riscv.ld)
else()
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_fsm.ld)
endif()
get_filename_component(ULP_LD_SCRIPT ${ULP_LD_TEMPLATE} NAME)
add_custom_command(OUTPUT ${ULP_LD_SCRIPT}
COMMAND ${CMAKE_C_COMPILER} -E -P -xc -o ${ULP_LD_SCRIPT} ${ULP_PREPROCESSOR_ARGS} ${ULP_LD_TEMPLATE}
@ -72,8 +76,19 @@ if(ULP_COCPU_IS_RISCV)
target_link_options(${ULP_APP_NAME} PRIVATE "-Wl,--no-warn-rwx-segments")
target_compile_definitions(${ULP_APP_NAME} PRIVATE IS_ULP_COCPU)
else()
elseif(ULP_COCPU_IS_LP_CORE)
list(APPEND ULP_S_SOURCES
"${IDF_PATH}/components/ulp/lp_core/lp_core/start.S"
"${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_startup.c")
target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles")
target_link_options(${ULP_APP_NAME} PRIVATE "-Wl,--no-warn-rwx-segments")
target_link_options(${ULP_APP_NAME} PRIVATE -Wl,--gc-sections)
target_link_options(${ULP_APP_NAME} PRIVATE -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map)
target_sources(${ULP_APP_NAME} PRIVATE ${ULP_S_SOURCES})
target_include_directories(${ULP_APP_NAME} PRIVATE "${IDF_PATH}/components/ulp/lp_core/lp_core/include")
else()
foreach(ulp_s_source ${ULP_S_SOURCES})
get_filename_component(ulp_ps_source ${ulp_s_source} NAME_WE)
set(ulp_ps_output ${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.ulp.S)
@ -96,9 +111,11 @@ else()
endif()
# Currently all the supported targets have the same base address of the ULP memory in the CPU address space.
# Modify this or pull this out of some SoC header file, if that becomes necessary.
if(ULP_COCPU_IS_LP_CORE)
set(ULP_BASE_ADDR "0x0")
else()
set(ULP_BASE_ADDR "0x50000000")
endif()
# Dump the list of global symbols in a convenient format
add_custom_command(OUTPUT ${ULP_APP_NAME}.sym

View File

@ -0,0 +1,15 @@
# CMake toolchain file for ULP LP core
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER "riscv32-esp-elf-gcc")
set(CMAKE_CXX_COMPILER "riscv32-esp-elf-g++")
set(CMAKE_ASM_COMPILER "riscv32-esp-elf-gcc")
set(CMAKE_C_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections"
CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections"
CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_ASM_FLAGS "-march=rv32imac -x assembler-with-cpp"
CACHE STRING "Assembler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-march=rv32imac_zicsr_zifencei --specs=nano.specs --specs=nosys.specs"
CACHE STRING "Linker Base Flags")

View File

@ -1,7 +1,3 @@
message(WARNING "Embedding ULP binary by including \
${IDF_PATH}/components/ulp/component_ulp_common.cmake is deprecated. Use `ulp_embed_binary` instead. \
See API Guide for more details.")
spaces2list(ULP_S_SOURCES)
spaces2list(ULP_EXP_DEP_SRCS)

View File

@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
ENTRY(reset_vector)
MEMORY
{
/*first 128byte for exception/interrupt vectors*/
vector_table(RX) : ORIGIN = 0x50000000, LENGTH = 0x80
ram(RWX) : ORIGIN = 0x50000080, LENGTH = CONFIG_ULP_COPROC_RESERVE_MEM - 0x80
}
SECTIONS
{
.vector.text :
{
/*exception/interrupt vectors*/
__mtvec_base = .;
KEEP (*(.init.vector .init.vector.*))
} > vector_table
. = ORIGIN(ram);
.text ALIGN(4):
{
*(.text.vectors) /* Default reset vector must link to offset 0x80 */
*(.text)
*(.text*)
} >ram
.rodata ALIGN(4):
{
*(.rodata)
*(.rodata*)
} > ram
.data ALIGN(4):
{
*(.data)
*(.data*)
*(.sdata)
*(.sdata*)
} > ram
.bss ALIGN(4) :
{
*(.bss)
*(.bss*)
*(.sbss)
*(.sbss*)
PROVIDE(end = .);
} >ram
__stack_top = ORIGIN(ram) + LENGTH(ram);
}

View File

@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include "esp_err.h"
#include "ulp_common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, // LP core is started by HP core (1 single wakeup)
} ulp_lp_core_wakeup_source_t;
/**
* @brief ULP LP core init parameters
*
*/
typedef struct {
ulp_lp_core_wakeup_source_t wakeup_source;
} ulp_lp_core_cfg_t;
/**
* @brief Configure the ULP
* and run the program loaded into RTC memory
*
* @return ESP_OK on success
*/
esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg);
/**
* @brief Load the program binary into RTC memory
*
* @param program_binary pointer to program binary
* @param program_size_bytes size of the program binary
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_SIZE if program_size_bytes is more than KiB
*/
esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_size_bytes);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "esp_log.h"
#include "soc/pmu_reg.h"
#include "soc/lpperi_reg.h"
#include "hal/misc.h"
#include "ulp_common.h"
#include "ulp_lp_core.h"
const static char* TAG = "ulp-lp-core";
esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg)
{
REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_WAKEUP_EN, 1);
switch(cfg->wakeup_source) {
case ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU:
REG_SET_FIELD(PMU_HP_LP_CPU_COMM_REG, PMU_HP_TRIGGER_LP, 1);
break;
default:
ESP_LOGE(TAG, "No valid wakeup source specified");
break;
}
return ESP_OK;
}
esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_size_bytes)
{
if (program_binary == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (program_size_bytes > CONFIG_ULP_COPROC_RESERVE_MEM) {
return ESP_ERR_INVALID_SIZE;
}
uint8_t* base = (uint8_t*) RTC_SLOW_MEM;
//Start by clearing memory reserved with zeros, this will also will initialize the bss:
hal_memset(base, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
hal_memcpy(base, program_binary, program_size_bytes);
return ESP_OK;
}

View File

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
extern void main();
/* Initialize lp core related system functions before calling user's main*/
void lp_core_startup()
{
main();
}

View File

@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
.section .text.vectors
.global reset_vector
/* The reset vector, jumps to startup code */
reset_vector:
j __start
__start:
/* setup the stack pointer */
la sp, __stack_top
call lp_core_startup
loop:
j loop

View File

@ -46,6 +46,9 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake)
set(ULP_IS_RISCV OFF)
endif()
elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE)
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-lp-core-riscv.cmake)
set(ULP_IS_LP_CORE_RISCV ON)
endif()
externalproject_add(${app_name}
@ -63,6 +66,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
-DSDKCONFIG_HEADER=${SDKCONFIG_HEADER}
-DPYTHON=${python}
-DULP_COCPU_IS_RISCV=${ULP_IS_RISCV}
-DULP_COCPU_IS_LP_CORE=${ULP_IS_LP_CORE_RISCV}
${extra_cmake_args}
BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${app_name} --target build
BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources}

View File

@ -0,0 +1,8 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers")
list(APPEND SDKCONFIG_DEFAULTS "sdkconfig.defaults")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lp_core_test)

View File

@ -0,0 +1,3 @@
| Supported Targets | ESP32-C6 |
| ----------------- | -------- |

View File

@ -0,0 +1,11 @@
set(app_sources "test_app_main.c" "test_lp_core.c")
set(lp_core_sources "lp_core/test_main.c")
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "lp_core"
REQUIRES ulp unity
WHOLE_ARCHIVE)
set(lp_core_app_name lp_core_test_app)
set(lp_core_exp_dep_srcs ${app_sources})
ulp_embed_binary(${lp_core_app_name} "${lp_core_sources}" "${lp_core_exp_dep_srcs}")

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "test_shared.h"
volatile lp_core_test_commands_t main_cpu_command = LP_CORE_NO_COMMAND;
volatile lp_core_test_command_reply_t main_cpu_reply = LP_CORE_COMMAND_INVALID;
volatile lp_core_test_commands_t command_resp = LP_CORE_NO_COMMAND;
volatile uint32_t test_data_in = 0;
volatile uint32_t test_data_out = 0;
volatile uint32_t counter = 0;
volatile uint32_t incrementer = 0;
void handle_commands(lp_core_test_commands_t cmd)
{
counter++;
switch (cmd) {
case LP_CORE_READ_WRITE_TEST:
/* Echo the command ID back to the main CPU */
command_resp = LP_CORE_READ_WRITE_TEST;
/* Process test data */
test_data_out = test_data_in ^ XOR_MASK;
/* Set the command reply status */
main_cpu_reply = LP_CORE_COMMAND_OK;
break;
case LP_CORE_NO_COMMAND:
main_cpu_reply = LP_CORE_COMMAND_OK;
break;
default:
main_cpu_reply = LP_CORE_COMMAND_NOK;
break;
}
}
int main (void)
{
while (1) {
handle_commands(main_cpu_command);
}
return 0;
}

View File

@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#define XOR_MASK 0xDEADBEEF
typedef enum{
LP_CORE_READ_WRITE_TEST = 1,
LP_CORE_NO_COMMAND,
} lp_core_test_commands_t;
typedef enum {
LP_CORE_COMMAND_OK = 1,
LP_CORE_COMMAND_NOK,
LP_CORE_COMMAND_INVALID,
} lp_core_test_command_reply_t;

View File

@ -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();
}

View File

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "lp_core_test_app.h"
#include "ulp_lp_core.h"
#include "test_shared.h"
#include "unity.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 bool firmware_loaded = false;
static void load_and_start_lp_core_firmware(void)
{
if (!firmware_loaded) {
ulp_lp_core_cfg_t cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
};
TEST_ASSERT(ulp_lp_core_load_binary(lp_core_main_bin_start,
(lp_core_main_bin_end - lp_core_main_bin_start)) == ESP_OK);
TEST_ASSERT(ulp_lp_core_run(&cfg) == ESP_OK);
firmware_loaded = true;
}
}
TEST_CASE("LP core and main CPU are able to exchange data", "[lp_core]")
{
const uint32_t test_data = 0x12345678;
/* Load ULP RISC-V firmware and start the coprocessor */
load_and_start_lp_core_firmware();
/* Setup test data */
ulp_test_data_in = test_data ^ XOR_MASK;
ulp_main_cpu_command = LP_CORE_READ_WRITE_TEST;
/* Wait till we receive the correct command response */
while (ulp_command_resp != LP_CORE_READ_WRITE_TEST) {
}
/* Verify test data */
TEST_ASSERT(ulp_command_resp == LP_CORE_READ_WRITE_TEST);
/* Wait till we receive COMMAND_OK reply */
while (ulp_main_cpu_reply != LP_CORE_COMMAND_OK) {
}
printf("data out: 0x%" PRIx32 ", expected: 0x%" PRIx32 " \n", ulp_test_data_out, test_data);
TEST_ASSERT(test_data == ulp_test_data_out);
/* Clear test data */
ulp_main_cpu_command = LP_CORE_NO_COMMAND;
}

View File

@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32c6
@pytest.mark.generic
def test_lp_core(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@ -0,0 +1,5 @@
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_ULP_COPROC_ENABLED=y
CONFIG_ULP_COPROC_TYPE_LP_CORE=y
CONFIG_ULP_COPROC_RESERVE_MEM=4096

View File

@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ULP_COMMON_DEFS_H__
#define __ULP_COMMON_DEFS_H__
#ifdef __cplusplus
extern "C" {
#endif
#define RTC_SLOW_MEM ((uint32_t*) 0x50000000) /*!< LP memory, 16k size */
#ifdef __cplusplus
}
#endif
#endif // __ULP_COMMON_DEFS_H__