Merge branch 'bugfix/rtc_fastmem_data_init' into 'master'

esp32: fixes related to CONFIG_ESP32_RTCDATA_IN_FAST_MEM

See merge request idf/esp-idf!3403
This commit is contained in:
Ivan Grokhotkov 2018-10-01 18:13:43 +08:00
commit 23984c8a03
7 changed files with 84 additions and 288 deletions

View file

@ -468,11 +468,15 @@ static bool should_load(uint32_t load_addr)
if (!load_rtc_memory) {
if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC code segment at 0x%08x\n", load_addr);
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
return false;
}
if (load_addr >= SOC_RTC_DRAM_LOW && load_addr < SOC_RTC_DRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
return false;
}
if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
ESP_LOGD(TAG, "Skipping RTC data segment at 0x%08x\n", load_addr);
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x\n", load_addr);
return false;
}
}

View file

@ -43,7 +43,7 @@ SECTIONS
data/rodata, including from any source file
named rtc_wake_stub*.c and the data marked with
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
The memory location of the data dependent on
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
*/
.rtc.data :
@ -65,6 +65,22 @@ SECTIONS
_rtc_bss_end = ABSOLUTE(.);
} > rtc_data_location
/* This section holds data that should not be initialized at power up
and will be retained during deep sleep.
User data marked with RTC_NOINIT_ATTR will be placed
into this section. See the file "esp_attr.h" for more information.
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
*/
.rtc_noinit (NOLOAD):
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} > rtc_data_location
/* This section located in RTC SLOW Memory area.
It holds data marked with RTC_SLOW_ATTR attribute.
See the file "esp_attr.h" for more information.
@ -78,28 +94,14 @@ SECTIONS
_rtc_force_slow_end = ABSOLUTE(.);
} > rtc_slow_seg
/* This section holds data that should not be initialized at power up
and will be retained during deep sleep. The section located in
RTC SLOW Memory area. User data marked with RTC_NOINIT_ATTR will be placed
into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} > rtc_slow_seg
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_noinit_end - _rtc_data_start)
: (_rtc_noinit_end - _rtc_force_slow_start);
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_bss_end - _rtc_fast_start);
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")

View file

@ -637,15 +637,11 @@ static uint32_t get_power_down_flags()
// If there is any data placed into .rtc.data or .rtc.bss segments, and
// RTC_SLOW_MEM is Auto, keep it powered up as well.
// These labels are defined in the linker script:
extern int _rtc_data_start, _rtc_data_end,
_rtc_bss_start, _rtc_bss_end,
_rtc_noinit_start, _rtc_noinit_end;
// Labels are defined in the linker script, see esp32.ld.
extern int _rtc_slow_length;
if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) &&
(&_rtc_data_end > &_rtc_data_start ||
&_rtc_bss_end > &_rtc_bss_start ||
&_rtc_noinit_end > &_rtc_noinit_start ||
((size_t) &_rtc_slow_length > 0 ||
(s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) {
s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON;
}

View file

@ -1,10 +1,14 @@
#include "unity.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "soc/soc.h"
static __NOINIT_ATTR uint32_t s_noinit;
static RTC_NOINIT_ATTR uint32_t s_rtc_noinit;
static RTC_DATA_ATTR uint32_t s_rtc_data;
static RTC_RODATA_ATTR uint32_t s_rtc_rodata;
static RTC_FAST_ATTR uint32_t s_rtc_force_fast;
static RTC_SLOW_ATTR uint32_t s_rtc_force_slow;
extern int _rtc_noinit_start;
extern int _rtc_noinit_end;
@ -12,6 +16,11 @@ extern int _rtc_data_start;
extern int _rtc_data_end;
extern int _noinit_start;
extern int _noinit_end;
extern int _rtc_force_fast_start;
extern int _rtc_force_fast_end;
extern int _rtc_force_slow_start;
extern int _rtc_force_slow_end;
static bool data_in_segment(void *ptr, int *seg_start, int *seg_end)
{
@ -24,4 +33,20 @@ TEST_CASE("Attributes place variables into correct sections", "[ld]")
TEST_ASSERT(data_in_segment(&s_noinit, &_noinit_start, &_noinit_end));
TEST_ASSERT(data_in_segment(&s_rtc_noinit, &_rtc_noinit_start, &_rtc_noinit_end));
TEST_ASSERT(data_in_segment(&s_rtc_data, &_rtc_data_start, &_rtc_data_end));
TEST_ASSERT(data_in_segment(&s_rtc_rodata, &_rtc_data_start, &_rtc_data_end));
TEST_ASSERT(data_in_segment(&s_rtc_force_fast, &_rtc_force_fast_start, &_rtc_force_fast_end));
TEST_ASSERT(data_in_segment(&s_rtc_force_slow, &_rtc_force_slow_start, &_rtc_force_slow_end));
#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
TEST_ASSERT(data_in_segment(&s_rtc_data, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH));
TEST_ASSERT(data_in_segment(&s_rtc_rodata, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH));
TEST_ASSERT(data_in_segment(&s_rtc_noinit, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH));
#else
TEST_ASSERT(data_in_segment(&s_rtc_data, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH));
TEST_ASSERT(data_in_segment(&s_rtc_rodata, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH));
TEST_ASSERT(data_in_segment(&s_rtc_noinit, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH));
#endif
TEST_ASSERT(data_in_segment(&s_rtc_force_fast, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH));
TEST_ASSERT(data_in_segment(&s_rtc_force_slow, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH));
}

View file

@ -6,12 +6,20 @@
#define RTC_BSS_ATTR __attribute__((section(".rtc.bss")))
#define CHECK_VALUE 0x89abcdef
static __NOINIT_ATTR uint32_t s_noinit_val;
static RTC_NOINIT_ATTR uint32_t s_rtc_noinit_val;
static RTC_DATA_ATTR uint32_t s_rtc_data_val;
static RTC_BSS_ATTR uint32_t s_rtc_bss_val;
/* There is no practical difference between placing something into RTC_DATA and
* RTC_RODATA. This only checks a usage pattern where the variable has a non-zero
* initializer (should be initialized by the bootloader).
*/
static RTC_RODATA_ATTR uint32_t s_rtc_rodata_val = CHECK_VALUE;
static RTC_FAST_ATTR uint32_t s_rtc_force_fast_val;
static RTC_SLOW_ATTR uint32_t s_rtc_force_slow_val;
#define CHECK_VALUE 0x89abcdef
static void setup_values()
{
@ -19,6 +27,10 @@ static void setup_values()
s_rtc_noinit_val = CHECK_VALUE;
s_rtc_data_val = CHECK_VALUE;
s_rtc_bss_val = CHECK_VALUE;
TEST_ASSERT_EQUAL_HEX32_MESSAGE(CHECK_VALUE, s_rtc_rodata_val,
"s_rtc_rodata_val should already be set up");
s_rtc_force_fast_val = CHECK_VALUE;
s_rtc_force_slow_val = CHECK_VALUE;
}
/* This test needs special test runners: rev1 silicon, and SPI flash with
@ -43,6 +55,9 @@ static void check_reset_reason_deep_sleep()
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_data_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_bss_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_rodata_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_force_fast_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_force_slow_val);
}
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_DEEPSLEEP", "[reset_reason][reset=DEEPSLEEP_RESET]",
@ -69,6 +84,9 @@ static void check_reset_reason_panic()
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_data_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_bss_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_rodata_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_fast_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_slow_val);
}
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after exception", "[reset_reason][reset=LoadStoreError,SW_CPU_RESET]",
@ -102,6 +120,9 @@ static void check_reset_reason_sw()
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_data_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_bss_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_rodata_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_fast_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_slow_val);
}
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart", "[reset_reason][reset=SW_CPU_RESET]",
@ -158,6 +179,9 @@ static void check_reset_reason_task_wdt()
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_data_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_bss_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_rodata_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_fast_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_slow_val);
}
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_TASK_WDT after task watchdog",
@ -201,6 +225,9 @@ static void check_reset_reason_brownout()
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_data_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_bss_val);
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_rodata_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_fast_val);
TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_slow_val);
}
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_BROWNOUT after brownout event",

View file

@ -1,260 +0,0 @@
// The lines below allow to skip test in configuration other then
// single_core which is required for this test to check placement in RTC_FAST memory
#include "sdkconfig.h"
#ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
#include "unity.h"
#include "esp_system.h"
#include "rom/rtc.h" // for rtc defines
#include "rom/uart.h" // for uart_tx_wait_idle()
#include "esp_log.h" // for log write functionality
#include "driver/rtc_io.h" // for gpio configuration
#include "esp_sleep.h" // include sleep related functionality
#include "soc/soc.h" // include access to soc macros
#include "soc/timer_group_reg.h" // for watchdog register defines
#include "soc/rtc_cntl_reg.h" // for rtc cntl register defines
#include "freertos/FreeRTOS.h" // for xPortGetCoreID
// Test notes:
// This test case sequence checks behavior of placement .rtc_data and .rtc_rodata sections
// into RTC_FAST memory. The Kconfig option CONFIG_ESP32_RTCDATA_IN_FAST_MEM
// is used to configure this behavior. The RTC_DATA_ATTR, RTC_RODATA_ATTR attributes
// can be used to place data into this area. If option is not set the .rtc_data
// and .rtc_rodata are placed in slow memory segment for compatibility.
// The only PRO_CPU can access the RTC_FAST memory, so the option CONFIG_FREERTOS_UNICORE
// should be enabled to place data into RTC_FAST memory segment.
#define ESP_EXT0_WAKEUP_LEVEL_LOW 0
#define ESP_EXT0_WAKEUP_LEVEL_HIGH 1
#define RTC_DATA_PATTERN 0xAAAAAAAA
#define RTC_RODATA_PATTERN 0x55555555
#define RTC_FAST_PATTERN 0xDDDDDDDD
#define RTC_SLOW_PATTERN 0x99999999
#define WAKE_STUB_PATTERN 0x77777777
#ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
#define CHECK_RTC_FAST_OPTION_ENABLED 1
#else
#define CHECK_RTC_FAST_OPTION_ENABLED 0
#endif
static RTC_DATA_ATTR uint32_t rtc_data = RTC_DATA_PATTERN;
static RTC_RODATA_ATTR uint32_t rtc_rodata = RTC_RODATA_PATTERN;
static RTC_FAST_ATTR uint32_t rtc_force_fast = RTC_FAST_PATTERN;
static RTC_SLOW_ATTR uint32_t rtc_force_slow = RTC_SLOW_PATTERN;
extern int _rtc_data_start;
extern int _rtc_data_end;
extern int _rtc_force_fast_start;
extern int _rtc_force_fast_end;
extern int _rtc_force_slow_start;
extern int _rtc_force_slow_end;
// This points to the values in RTC memory
static uint32_t *rtc_data_val_addr = (uint32_t*)&rtc_data;
static uint32_t *rtc_rodata_val_addr = (uint32_t*)&rtc_rodata;
static uint32_t *rtc_fast_val_addr = (uint32_t*)&rtc_force_fast;
static uint32_t *rtc_slow_val_addr = (uint32_t*)&rtc_force_slow;
static const char* tag = "rtc_data_fast_UnitTestMain";
static void RTC_IRAM_ATTR wake_stub(void);
static void RTC_IRAM_ATTR wake_stub_dummy(void)
{
rtc_data = WAKE_STUB_PATTERN;
set_rtc_memory_crc(); // update rtc memory CRC
}
static esp_err_t check_data_placement(uint32_t *value_address,
uint32_t *seg_start, uint32_t *seg_end)
{
esp_err_t result = ESP_FAIL;
if (((uint32_t)value_address <= (uint32_t)seg_end)
&& ((uint32_t)value_address >= (uint32_t)seg_start)){
result = ESP_OK;
}
return result;
}
static esp_err_t check_wake_stub_status(void)
{
esp_err_t result = ESP_FAIL;
uint32_t entry_addr = REG_READ(RTC_ENTRY_ADDR_REG);
if (entry_addr == (uint32_t)&wake_stub_dummy) {
result = ESP_OK;
} else if (entry_addr == (uint32_t)&wake_stub) {
result = ESP_ERR_INVALID_STATE;
} else {
result = ESP_FAIL;
}
return result;
}
static void RTC_IRAM_ATTR wake_stub(void)
{
esp_default_wake_deep_sleep();
// Set the pointer of the new wake stub function.
// It will be checked in test to make sure the wake stub entered
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&wake_stub_dummy);
// Set this value to check it in test later
rtc_data = WAKE_STUB_PATTERN;
set_rtc_memory_crc(); // update rtc memory CRC
}
static void setup_deep_sleep(void)
{
// Set wake stub function to check its behavior
// This function sets checksum of RTC fast memory appropriately
esp_set_deep_sleep_wake_stub(&wake_stub);
// Setup ext0 configuration to wake up immediately
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
uart_tx_wait_idle(0);
esp_deep_sleep_start();
}
// The lines below are required to suppress GCC warnings about casting of function pointers
// in unity macro expansion. These warnings may be treated as errors during automated test.
#pragma GCC diagnostic push // required for GCC
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
static void reset_reason_power_on(void)
{
printf("This test case verifies behavior of RTC_DATA variables after reset. \n");
RESET_REASON reason = rtc_get_reset_reason(0);
TEST_ASSERT(reason == POWERON_RESET || reason == RTCWDT_RTC_RESET);
ESP_LOGI(tag, "Reset reason=(%d)", (uint16_t)reason);
printf("rtc_data_val = (0x%X), rtc_rodata_val = (0x%X), rtc_fast_val = (0x%X), rtc_slow_val = (0x%X)\r\n",
(uint32_t)*rtc_data_val_addr, (uint32_t)*rtc_rodata_val_addr,
(uint32_t)*rtc_fast_val_addr, (uint32_t)*rtc_slow_val_addr);
printf("This test case called by CPU%u\r\n", (uint16_t)xPortGetCoreID());
TEST_ASSERT(CHECK_RTC_FAST_OPTION_ENABLED == 1);
printf("Check that values are placed in correct sections and then compare its values with patterns.\r\n");
TEST_ASSERT(check_data_placement(rtc_fast_val_addr,
(uint32_t*)&_rtc_force_fast_start,
(uint32_t*)&_rtc_force_fast_end) == ESP_OK);
TEST_ASSERT(check_data_placement(rtc_data_val_addr,
(uint32_t*)&_rtc_data_start,
(uint32_t*)&_rtc_data_end) == ESP_OK);
TEST_ASSERT(check_data_placement(rtc_rodata_val_addr,
(uint32_t*)&_rtc_data_start,
(uint32_t*)&_rtc_data_end) == ESP_OK);
printf("Values RTC_DATA_ATTR, RTC_FAST_ATTR are placed in section (0x%x - 0x%x).\r\n",
(uint32_t)&_rtc_data_start, (uint32_t)&_rtc_data_end);
TEST_ASSERT(check_data_placement(rtc_slow_val_addr,
(uint32_t*)&_rtc_force_slow_start,
(uint32_t*)&_rtc_force_slow_end) == ESP_OK);
printf("The RTC_SLOW values are placed in slow memory (0x%X - 0x%X).\r\n",
(uint32_t)&_rtc_force_slow_start, (uint32_t)&_rtc_force_slow_end);
TEST_ASSERT(RTC_RODATA_PATTERN == *rtc_rodata_val_addr);
TEST_ASSERT(RTC_DATA_PATTERN == *rtc_data_val_addr);
TEST_ASSERT(RTC_FAST_PATTERN == *rtc_fast_val_addr);
TEST_ASSERT(RTC_SLOW_PATTERN == *rtc_slow_val_addr);
printf("The values correspond to its patterns.\r\n");
printf("Go to deep sleep to check DEEP_SLEEP_RESET behavior. \r\n");
setup_deep_sleep();
}
static void reset_reason_deep_sleep(void)
{
printf("This test case checks behavior of RTC_DATA variables after deep sleep reset. \r\n");
RESET_REASON reason = rtc_get_reset_reason(0);
ESP_LOGI(tag, "Reset reason=(%d)", (uint16_t)reason);
printf("rtc_data_val = (0x%X), rtc_rodata_val = (0x%X), rtc_fast_val = (0x%X), rtc_slow_val = (0x%X)\r\n",
(uint32_t)*rtc_data_val_addr, (uint32_t)*rtc_rodata_val_addr,
(uint32_t)*rtc_fast_val_addr, (uint32_t)*rtc_slow_val_addr);
TEST_ASSERT(reason == DEEPSLEEP_RESET);
if (CHECK_RTC_FAST_OPTION_ENABLED == 1) {
printf("The CONFIG_ESP32_RTCDATA_IN_FAST_MEM is active means placement of RTC_DATA in fast segment.\r\n");
} else {
printf("The CONFIG_ESP32_RTCDATA_IN_FAST_MEM is not set. Please set this option\r\n");
printf("in menuconfig to check .rtc.data placement in RTC fast memory.\r\n");
}
TEST_ASSERT(CHECK_RTC_FAST_OPTION_ENABLED == 1);
// Check if deep sleep wake stub has been entered
// this means CRC was correct
if (check_wake_stub_status() == ESP_OK) {
printf("The wake stub has been executed means CRC was correct.\r\n");
} else {
printf("The wake stub is not executed.\r\n");
}
TEST_ASSERT(check_wake_stub_status() == ESP_OK);
// If the RTC CRC is incorrect the function return NULL
if (esp_get_deep_sleep_wake_stub() == NULL){
printf("The wake stub has changed the value of rtc_data as expected.\r\n");
} else {
printf("The rtc_data value is not changed that is incorrect. \r\n");
}
TEST_ASSERT(esp_get_deep_sleep_wake_stub() == NULL);
TEST_ASSERT(check_data_placement(rtc_data_val_addr,
(uint32_t*)&_rtc_data_start,
(uint32_t*)&_rtc_data_end) == ESP_OK);
TEST_ASSERT(check_data_placement(rtc_rodata_val_addr,
(uint32_t*)&_rtc_data_start,
(uint32_t*)&_rtc_data_end) == ESP_OK);
TEST_ASSERT(check_data_placement(rtc_fast_val_addr,
(uint32_t*)&_rtc_force_fast_start,
(uint32_t*)&_rtc_force_fast_end) == ESP_OK);
printf("Values RTC_DATA_ATTR, RTC_FAST_ATTR are placed in RTC fast segment (0x%x - 0x%x).\r\n",
(uint32_t)&_rtc_data_start, (uint32_t)&_rtc_data_end);
TEST_ASSERT(check_data_placement(rtc_slow_val_addr,
(uint32_t*)&_rtc_force_slow_start,
(uint32_t*)&_rtc_force_slow_end) == ESP_OK);
printf("The RTC_SLOW values are placed in slow memory (0x%X - 0x%X).\r\n",
(uint32_t)&_rtc_force_slow_start, (uint32_t)&_rtc_force_slow_end);
TEST_ASSERT(RTC_DATA_PATTERN == *rtc_data_val_addr);
TEST_ASSERT(RTC_RODATA_PATTERN == *rtc_rodata_val_addr);
TEST_ASSERT(RTC_FAST_PATTERN == *rtc_fast_val_addr);
TEST_ASSERT(RTC_SLOW_PATTERN == *rtc_slow_val_addr);
printf("Values correspond to its patterns.\r\n");
printf("The test cases are done.. \r\n");
}
// The multiple stages test case to check values after certain reset reason
TEST_CASE_MULTIPLE_STAGES("RTC_DATA attributes behavior", \
"[restart][reset=DEEPSLEEP_RESET]",
reset_reason_power_on, reset_reason_deep_sleep);
#pragma GCC diagnostic pop // require GCC
#endif // CONFIG_ESP32_RTCDATA_IN_FAST_MEM

View file

@ -288,6 +288,8 @@
#define SOC_IRAM_HIGH 0x400A0000
#define SOC_RTC_IRAM_LOW 0x400C0000
#define SOC_RTC_IRAM_HIGH 0x400C2000
#define SOC_RTC_DRAM_LOW 0x3FF80000
#define SOC_RTC_DRAM_HIGH 0x3FF82000
#define SOC_RTC_DATA_LOW 0x50000000
#define SOC_RTC_DATA_HIGH 0x50002000