mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(esp_hw_support): check psram data is not corrupted after lightsleep
This commit is contained in:
committed by
Song Ruo Jing
parent
8950ee3cd9
commit
bc55111320
@@ -13,7 +13,9 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
#include "esp_cpu.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_ipc_isr.h"
|
||||||
#include "esp_private/esp_psram_io.h"
|
#include "esp_private/esp_psram_io.h"
|
||||||
#include "esp_psram.h"
|
#include "esp_psram.h"
|
||||||
#include "esp_private/esp_psram_extram.h"
|
#include "esp_private/esp_psram_extram.h"
|
||||||
@@ -27,14 +29,14 @@ __attribute__((unused)) const static char *TAG = "PSRAM";
|
|||||||
static void s_test_psram_heap_allocable(void)
|
static void s_test_psram_heap_allocable(void)
|
||||||
{
|
{
|
||||||
size_t largest_size = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
|
size_t largest_size = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
|
||||||
ESP_LOGI(TAG, "largest size is %zu", largest_size);
|
ESP_EARLY_LOGI(TAG, "largest size is 0x%08x", largest_size);
|
||||||
|
|
||||||
uint32_t *ext_buffer = (uint32_t *)heap_caps_calloc(largest_size, 1, MALLOC_CAP_SPIRAM);
|
uint32_t *ext_buffer = (uint32_t *)heap_caps_calloc(largest_size, 1, MALLOC_CAP_SPIRAM);
|
||||||
TEST_ASSERT(ext_buffer);
|
TEST_ASSERT(ext_buffer);
|
||||||
|
|
||||||
intptr_t start = (intptr_t)ext_buffer;
|
intptr_t start = (intptr_t)ext_buffer;
|
||||||
intptr_t end = (intptr_t)ext_buffer + largest_size;
|
intptr_t end = (intptr_t)ext_buffer + largest_size;
|
||||||
ESP_LOGI(TAG, "test ext buffer start addr is 0x%"PRIxPTR", end addr is 0x%"PRIxPTR, start, end);
|
ESP_EARLY_LOGI(TAG, "test ext buffer start addr is %p, end addr is %p", start, end);
|
||||||
TEST_ASSERT(esp_psram_check_ptr_addr((void *)start) && esp_psram_check_ptr_addr((void *)end));
|
TEST_ASSERT(esp_psram_check_ptr_addr((void *)start) && esp_psram_check_ptr_addr((void *)end));
|
||||||
|
|
||||||
for (int i = 0; i < largest_size / sizeof(uint32_t); i++) {
|
for (int i = 0; i < largest_size / sizeof(uint32_t); i++) {
|
||||||
@@ -61,16 +63,32 @@ TEST_CASE("stress test psram heap allocable", "[psram][manual][ignore]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_SPIRAM_XIP_FROM_PSRAM
|
#if !CONFIG_SPIRAM_XIP_FROM_PSRAM
|
||||||
|
|
||||||
|
IRAM_ATTR static void s_psram_halfsleep_test(uint32_t rtc_slow_clk_period)
|
||||||
|
{
|
||||||
|
// Stall another core and disable branch predictor to prevent it from accessing PSRAM
|
||||||
|
esp_ipc_isr_stall_other_cpu();
|
||||||
|
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||||
|
esp_cpu_branch_prediction_disable();
|
||||||
|
#endif
|
||||||
|
esp_psram_impl_enter_halfsleep_mode();
|
||||||
|
esp_rom_delay_us(1000);
|
||||||
|
esp_psram_impl_exit_halfsleep_mode();
|
||||||
|
esp_psram_impl_resume_from_halfsleep_mode(rtc_slow_clk_period);
|
||||||
|
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||||
|
esp_cpu_branch_prediction_enable();
|
||||||
|
#endif
|
||||||
|
esp_ipc_isr_release_other_cpu();
|
||||||
|
|
||||||
|
s_test_psram_heap_allocable();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("test psram halfsleep mode (if applicable)", "[psram]")
|
TEST_CASE("test psram halfsleep mode (if applicable)", "[psram]")
|
||||||
{
|
{
|
||||||
uint32_t rtc_slow_clk_period = rtc_clk_cal(CLK_CAL_RTC_SLOW, CONFIG_RTC_CLK_CAL_CYCLES);
|
uint32_t rtc_slow_clk_period = rtc_clk_cal(CLK_CAL_RTC_SLOW, CONFIG_RTC_CLK_CAL_CYCLES);
|
||||||
s_test_psram_heap_allocable();
|
s_test_psram_heap_allocable();
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
esp_psram_impl_enter_halfsleep_mode();
|
s_psram_halfsleep_test(rtc_slow_clk_period);
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
esp_psram_impl_exit_halfsleep_mode();
|
|
||||||
esp_psram_impl_resume_from_halfsleep_mode(rtc_slow_clk_period);
|
|
||||||
s_test_psram_heap_allocable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -320,6 +320,24 @@ static void test_psram_accessible_after_lightsleep(void)
|
|||||||
TEST_ESP_OK(sleep_cpu_configure(true));
|
TEST_ESP_OK(sleep_cpu_configure(true));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Verify PSRAM was not corrupted after light sleep
|
||||||
|
uint8_t *psram_data = (uint8_t *)heap_caps_malloc(1024 * 1024, MALLOC_CAP_SPIRAM);
|
||||||
|
uint8_t test_pattern = 0x5a;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
memset(psram_data, test_pattern, 1024 * 1024);
|
||||||
|
esp_sleep_enable_timer_wakeup(100 * 1000);
|
||||||
|
esp_light_sleep_start();
|
||||||
|
for (int j = 0; j < (1024 * 1024); j++) {
|
||||||
|
TEST_ASSERT_EQUAL(test_pattern, psram_data[j]);
|
||||||
|
}
|
||||||
|
test_pattern = ~test_pattern;
|
||||||
|
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||||
|
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
free(psram_data);
|
||||||
|
|
||||||
|
// Verify that all addresses in PSRAM are accessible after light sleep
|
||||||
esp_sleep_enable_timer_wakeup(100 * 1000);
|
esp_sleep_enable_timer_wakeup(100 * 1000);
|
||||||
esp_light_sleep_start();
|
esp_light_sleep_start();
|
||||||
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
|
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
|
||||||
|
|||||||
Reference in New Issue
Block a user