Merge branch 'bugfix/p4_reserved_rtc_mem' into 'master'

fix(rtc_memory): fix conflict between LP-ROM and RTC reserved

Closes IDF-9408

See merge request espressif/esp-idf!30012
This commit is contained in:
Marius Vikhammer
2024-04-17 16:45:57 +08:00
19 changed files with 289 additions and 33 deletions

View File

@@ -212,6 +212,12 @@ tools/test_apps/system/ram_loadable_app:
- if: IDF_TARGET in ["esp32p4"]
temporary: true
reason: TBD # TODO: IDF-8994
tools/test_apps/system/rtc_mem_reserve:
enable:
- if: IDF_TARGET in ["esp32p4"]
reason: only P4 has a potential conflict due to using rtc mem for lp rom data/stack
tools/test_apps/system/startup:
disable:
- if: CONFIG_NAME == "main_task_cpu1" and IDF_TARGET not in ["esp32", "esp32s3"]

View File

@@ -0,0 +1,9 @@
# 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)
set(COMPONENTS main)
project(test_rtc_memory_reserve)

View File

@@ -0,0 +1,2 @@
| Supported Targets | ESP32-P4 |
| ----------------- | -------- |

View File

@@ -0,0 +1,24 @@
idf_component_register(SRCS "rtc_mem_reserve_test_main.c"
INCLUDE_DIRS "."
REQUIRES ulp bootloader_support unity esp_mm)
#
# ULP support additions to component CMakeLists.txt.
#
# 1. The ULP app name must be unique (if multiple components use ULP).
set(ulp_app_name ulp_${COMPONENT_NAME})
#
# 2. Specify all C and Assembly source files.
# Files should be placed into a separate directory (in this case, ulp/),
# which should not be added to COMPONENT_SRCS.
set(ulp_sources "ulp/main.c")
#
# 3. List all the component source files which include automatically
# generated ULP export file, ${ulp_app_name}.h:
set(ulp_exp_dep_srcs ${app_sources})
#
# 4. Call function to build ULP binary and embed in project using the argument
# values above.
ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")

View File

@@ -0,0 +1,123 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/*
* This is an integration test for bootloader RTC reserve memory + ULP
* These both rely on the same RTC memory region, so we need to make sure they don't
* cause any conflict.
*/
#include "sdkconfig.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "bootloader_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ulp_lp_core.h"
#include "ulp_main.h"
#include "unity.h"
#include "unity_test_runner.h"
#include "esp_cache.h"
#define TEST_MAGIC_VALUE_A 0x42987561
#define TEST_MAGIC_VALUE_B 0x32234701
#define TEST_MAGIC_VALUE_C 0x62312178
#define UNINITIALIZED_HEAP_VAL 0xCECECECE // From CONFIG_HEAP_POISONING_COMPREHENSIVE
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
extern rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);
#define ULP_SLEEP_DURATION_US 10000
#define HEAP_ALLOC_SIZE 0x1000
static void init_ulp_program(void)
{
esp_err_t err = ulp_lp_core_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
ESP_ERROR_CHECK(err);
/* Start the program */
ulp_lp_core_cfg_t cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER,
.lp_timer_sleep_duration_us = ULP_SLEEP_DURATION_US,
};
err = ulp_lp_core_run(&cfg);
ESP_ERROR_CHECK(err);
}
static volatile RTC_DATA_ATTR uint32_t rtc_data_var = TEST_MAGIC_VALUE_B;
static volatile RTC_IRAM_ATTR uint32_t rtc_text_var = TEST_MAGIC_VALUE_C;
static bool ulp_is_running(uint32_t *counter_variable)
{
uint32_t start_cnt = *counter_variable;
/* Wait a few ULP wakeup cycles to ensure ULP has run */
vTaskDelay((5 * ULP_SLEEP_DURATION_US / 1000) / portTICK_PERIOD_MS);
uint32_t end_cnt = *counter_variable;
printf("start run count: %" PRIu32 ", end run count %" PRIu32 "\n", start_cnt, end_cnt);
/* If the ulp is running the counter should have been incremented */
return (start_cnt != end_cnt);
}
TEST_CASE("ULP do not corrupt RTC memory used by APP", "[rtc_mem_reserve]")
{
rtc_retain_mem_t* mem = bootloader_common_get_rtc_retain_mem();
uint32_t* _rtc_vars = (uint32_t*) mem->custom;
uint32_t *rtc_heap = heap_caps_malloc(HEAP_ALLOC_SIZE, MALLOC_CAP_RTCRAM);
printf("Checking RTC reserve memory at %p\n", _rtc_vars);
printf("Checking RTC heap memory at %p\n", rtc_heap);
printf("Checking RTC data var at %p\n", &rtc_data_var);
printf("Checking RTC text var at %p\n", &rtc_text_var);
TEST_ASSERT_EACH_EQUAL_HEX(TEST_MAGIC_VALUE_A, _rtc_vars, CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t));
TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_B, rtc_data_var);
TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_C, rtc_text_var);
TEST_ASSERT_EACH_EQUAL_HEX(UNINITIALIZED_HEAP_VAL, rtc_heap, HEAP_ALLOC_SIZE / sizeof(uint32_t));
init_ulp_program();
// Let the ULP run for a few times to see
// if it corrupts the RTC memory or not
TEST_ASSERT(ulp_is_running(&ulp_run_counter));
TEST_ASSERT_EACH_EQUAL_HEX(TEST_MAGIC_VALUE_A, _rtc_vars, CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t));
TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_B, rtc_data_var);
TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_C, rtc_text_var);
TEST_ASSERT_EACH_EQUAL_HEX(UNINITIALIZED_HEAP_VAL, rtc_heap, HEAP_ALLOC_SIZE / sizeof(uint32_t));
}
void app_main(void)
{
rtc_retain_mem_t* mem = bootloader_common_get_rtc_retain_mem();
uint32_t* _rtc_vars = (uint32_t*) mem->custom;
esp_reset_reason_t reset_reason = esp_reset_reason();
printf("RTC reserve memory placed at %p\n", _rtc_vars);
printf("RTC data var placed at %p\n", &rtc_data_var);
if (reset_reason == ESP_RST_POWERON) {
printf("First boot, set RTC values and restart\n");
for(int i = 0; i < CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t); i++) {
_rtc_vars[i] = TEST_MAGIC_VALUE_A;
}
TEST_ASSERT_EACH_EQUAL_HEX(TEST_MAGIC_VALUE_A, _rtc_vars, CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t));
TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_B, rtc_data_var);
TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_C, rtc_text_var);
esp_restart();
}
unity_run_menu();
}

View File

@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdint.h>
#include "ulp_lp_core.h"
#include "ulp_lp_core_utils.h"
/* this variable will be exported as a public symbol, visible from main CPU: */
volatile uint32_t run_counter = 0;
int main (void)
{
run_counter++;
/* ulp_lp_core_halt() is called automatically when main exits */
return 0;
}

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32p4
@pytest.mark.generic
def test_rtc_mem_reserve(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@@ -0,0 +1,10 @@
CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0x10
CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC=y
CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE=0x200
CONFIG_ESP_TASK_WDT_EN=n
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
# Enable ULP
CONFIG_ULP_COPROC_ENABLED=y
CONFIG_ULP_COPROC_TYPE_LP_CORE=y
CONFIG_ULP_COPROC_RESERVE_MEM=4096