Merge branch 'fix/p4_ulp_shared_mem' into 'master'

fix(lp-core): fixed ULP shared mem address being wrong on P4

See merge request espressif/esp-idf!32237
This commit is contained in:
Marius Vikhammer 2024-07-24 13:54:08 +08:00
commit f47338122f
7 changed files with 135 additions and 6 deletions

View File

@ -14,13 +14,20 @@
#define ULP_MEM_START_ADDRESS (SOC_RTC_DRAM_LOW) #define ULP_MEM_START_ADDRESS (SOC_RTC_DRAM_LOW)
#endif #endif
#define ALIGN_DOWN(SIZE, AL) (SIZE & ~(AL - 1))
/* Ensure the end where the shared memory starts is aligned to 8 bytes
if updating this also update the same in ulp_lp_core_memory_shared.c
*/
#define ALIGNED_COPROC_MEM ALIGN_DOWN(CONFIG_ULP_COPROC_RESERVE_MEM, 0x8)
ENTRY(reset_vector) ENTRY(reset_vector)
MEMORY MEMORY
{ {
/*first 128byte for exception/interrupt vectors*/ /*first 128byte for exception/interrupt vectors*/
vector_table(RX) : ORIGIN = ULP_MEM_START_ADDRESS , LENGTH = 0x80 vector_table(RX) : ORIGIN = ULP_MEM_START_ADDRESS , LENGTH = 0x80
ram(RWX) : ORIGIN = ULP_MEM_START_ADDRESS + 0x80, LENGTH = CONFIG_ULP_COPROC_RESERVE_MEM - 0x80 - CONFIG_ULP_SHARED_MEM ram(RWX) : ORIGIN = ULP_MEM_START_ADDRESS + 0x80, LENGTH = ALIGNED_COPROC_MEM - 0x80 - CONFIG_ULP_SHARED_MEM
shared_mem_ram(RW) : ORIGIN = ULP_MEM_START_ADDRESS + ALIGNED_COPROC_MEM - CONFIG_ULP_SHARED_MEM, LENGTH = CONFIG_ULP_SHARED_MEM
} }
SECTIONS SECTIONS
@ -65,4 +72,10 @@ SECTIONS
} >ram } >ram
__stack_top = ORIGIN(ram) + LENGTH(ram); __stack_top = ORIGIN(ram) + LENGTH(ram);
. = ORIGIN(shared_mem_ram);
.shared_mem (ALIGN(4)) :
{
KEEP(*(.shared_mem))
} > shared_mem_ram
} }

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -7,21 +7,37 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "esp_rom_caps.h"
#include "esp_assert.h" #include "esp_assert.h"
#define ALIGN_DOWN(SIZE, AL) (SIZE & ~(AL - 1))
/* The last CONFIG_ULP_SHARED_MEM bytes of the reserved memory are reserved for a shared cfg struct /* The last CONFIG_ULP_SHARED_MEM bytes of the reserved memory are reserved for a shared cfg struct
The main cpu app and the ulp binary can share variables automatically through the linkerscript generated from The main cpu app and the ulp binary can share variables automatically through the linkerscript generated from
esp32ulp_mapgen.py, but this is not available when compiling the ULP library. esp32ulp_mapgen.py, but this is not available when compiling the ULP library.
For those special cases, e.g. config settings. We can use this shared area. For those special cases, e.g. config settings. We can use this shared area.
*/ */
#define LP_CORE_SHARED_MEM_ADDR (SOC_RTC_DRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM - CONFIG_ULP_SHARED_MEM)
static ulp_lp_core_memory_shared_cfg_t *const s_shared_mem = (ulp_lp_core_memory_shared_cfg_t *)LP_CORE_SHARED_MEM_ADDR;
#if IS_ULP_COCPU
static ulp_lp_core_memory_shared_cfg_t __attribute__((section(".shared_mem"))) s_shared_mem = {};
ESP_STATIC_ASSERT(CONFIG_ULP_SHARED_MEM == sizeof(ulp_lp_core_memory_shared_cfg_t)); ESP_STATIC_ASSERT(CONFIG_ULP_SHARED_MEM == sizeof(ulp_lp_core_memory_shared_cfg_t));
#endif
ulp_lp_core_memory_shared_cfg_t* ulp_lp_core_memory_shared_cfg_get(void) ulp_lp_core_memory_shared_cfg_t* ulp_lp_core_memory_shared_cfg_get(void)
{ {
return s_shared_mem; #if IS_ULP_COCPU
return &s_shared_mem;
#else
#if ESP_ROM_HAS_LP_ROM
extern uint32_t _rtc_ulp_memory_start;
uint32_t ulp_base_addr = (uint32_t)&_rtc_ulp_memory_start;
#else
uint32_t ulp_base_addr = SOC_RTC_DRAM_LOW;
#endif
/* Ensure the end where the shared memory starts is aligned to 8 bytes
if updating this also update the same in ulp_lp_core_riscv.ld
*/
return (ulp_lp_core_memory_shared_cfg_t *)(ulp_base_addr + ALIGN_DOWN(CONFIG_ULP_COPROC_RESERVE_MEM, 0x8) - CONFIG_ULP_SHARED_MEM);
#endif
} }

View File

@ -1,6 +1,7 @@
set(app_sources "test_app_main.c" "test_lp_core.c") set(app_sources "test_app_main.c" "test_lp_core.c")
set(lp_core_sources "lp_core/test_hello_main.c") set(lp_core_sources "lp_core/test_hello_main.c")
set(lp_core_sources_panic "lp_core/test_panic_main.c") set(lp_core_sources_panic "lp_core/test_panic_main.c")
set(lp_core_sources_shared_mem "lp_core/test_shared_mem_main.c")
idf_component_register(SRCS ${app_sources} idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "lp_core" INCLUDE_DIRS "lp_core"
@ -11,3 +12,4 @@ set(lp_core_exp_dep_srcs ${app_sources})
ulp_embed_binary(lp_core_test_app "${lp_core_sources}" "${lp_core_exp_dep_srcs}") ulp_embed_binary(lp_core_test_app "${lp_core_sources}" "${lp_core_exp_dep_srcs}")
ulp_embed_binary(lp_core_test_app_panic "${lp_core_sources_panic}" "${lp_core_exp_dep_srcs}") ulp_embed_binary(lp_core_test_app_panic "${lp_core_sources_panic}" "${lp_core_exp_dep_srcs}")
ulp_embed_binary(lp_core_test_app_shared_mem "${lp_core_sources_shared_mem}" "${lp_core_exp_dep_srcs}")

View File

@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#define SHARED_MEM_INIT_VALUE 0xEE
#define SHARED_MEM_END_VALUE 0xAA

View File

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "ulp_lp_core_print.h"
#include "ulp_lp_core_memory_shared.h"
#include "test_shared.h"
int main(void)
{
ulp_lp_core_memory_shared_cfg_t *shared_cfg = ulp_lp_core_memory_shared_cfg_get();
lp_core_printf("ULP shared memory address: %p\n", shared_cfg);
volatile uint8_t* shared_mem = (uint8_t*)shared_cfg;
for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) {
if (shared_mem[i] != SHARED_MEM_INIT_VALUE) {
lp_core_printf("Test failed: expected %X, got %X at %d\n", SHARED_MEM_INIT_VALUE, shared_mem[i], i);
return 0;
}
}
for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) {
shared_mem[i] = SHARED_MEM_END_VALUE;
}
lp_core_printf("ULP shared memory test passed\n");
return 0;
}

View File

@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <inttypes.h> #include <inttypes.h>
#include <sys/time.h> #include <sys/time.h>
#include <string.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@ -15,6 +16,8 @@
#include "esp_rom_caps.h" #include "esp_rom_caps.h"
#include "lp_core_test_app.h" #include "lp_core_test_app.h"
#include "ulp_lp_core.h" #include "ulp_lp_core.h"
#include "ulp_lp_core_memory_shared.h"
#include "test_shared.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_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"); extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end");
@ -22,6 +25,9 @@ extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_
extern const uint8_t lp_core_panic_bin_start[] asm("_binary_lp_core_test_app_panic_bin_start"); extern const uint8_t lp_core_panic_bin_start[] asm("_binary_lp_core_test_app_panic_bin_start");
extern const uint8_t lp_core_panic_bin_end[] asm("_binary_lp_core_test_app_panic_bin_end"); extern const uint8_t lp_core_panic_bin_end[] asm("_binary_lp_core_test_app_panic_bin_end");
extern const uint8_t lp_core_shared_mem_bin_start[] asm("_binary_lp_core_test_app_shared_mem_bin_start");
extern const uint8_t lp_core_shared_mem_bin_end[] asm("_binary_lp_core_test_app_shared_mem_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) 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, TEST_ASSERT(ulp_lp_core_load_binary(firmware_start,
@ -58,3 +64,32 @@ TEST_CASE("LP-Core panic", "[lp_core]")
// We simply wait to allow the lp-core to run once // We simply wait to allow the lp-core to run once
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
} }
TEST_CASE("LP-Core Shared-mem", "[lp_core]")
{
/* Load ULP firmware and start the coprocessor */
ulp_lp_core_cfg_t cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
};
TEST_ASSERT(ulp_lp_core_load_binary(lp_core_shared_mem_bin_start, (lp_core_shared_mem_bin_end - lp_core_shared_mem_bin_start)) == ESP_OK);
printf("HP shared memory address: %p\n", ulp_lp_core_memory_shared_cfg_get());
volatile uint8_t* shared_mem = (uint8_t*)ulp_lp_core_memory_shared_cfg_get();
for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) {
shared_mem[i] = SHARED_MEM_INIT_VALUE;
}
TEST_ASSERT(ulp_lp_core_run(&cfg) == ESP_OK);
// 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);
// Check that ULP set the shared memory to 0xAA, and it did not get overwritten by anything
for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) {
TEST_ASSERT_EQUAL(SHARED_MEM_END_VALUE, shared_mem[i]);
}
printf("HP shared memory test passed\n");
}

View File

@ -27,3 +27,23 @@ def test_lp_core_panic(dut: Dut) -> None:
dut.expect_exact("Guru Meditation Error: LP Core panic'ed Breakpoint") dut.expect_exact("Guru Meditation Error: LP Core panic'ed Breakpoint")
dut.expect_exact('Core 0 register dump:') dut.expect_exact('Core 0 register dump:')
dut.expect_exact('ELF file SHA256:') dut.expect_exact('ELF file SHA256:')
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32p4
@pytest.mark.generic
def test_lp_core_shared_mem(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('"LP-Core Shared-mem"')
result = dut.expect(r'HP shared memory address: (0x[0-9a-fA-F]+)')
hp_addr = result[1]
result = dut.expect(r'ULP shared memory address: (0x[0-9a-fA-F]+)')
ulp_addr = result[1]
assert ulp_addr == hp_addr
dut.expect_exact('ULP shared memory test passed')
dut.expect_exact('HP shared memory test passed')