Merge branch 'bugfix/deep_sleep_skip_verify_rtc_mem_heap' into 'master'

Fix bootloader "skip validate on exiting deep sleep" option if "use RTC memory as heap" is enabled

See merge request espressif/esp-idf!12032
This commit is contained in:
Angus Gratton 2021-04-15 23:56:39 +00:00
commit bc3d45026c
10 changed files with 113 additions and 23 deletions

View File

@ -330,6 +330,7 @@ test_app_test_003:
test_app_test_004:
extends: .test_app_esp32s2_template
parallel: 2
tags:
- ESP32S2
- Example_GENERIC

View File

@ -30,6 +30,7 @@
#include "soc/gpio_periph.h"
#include "soc/rtc.h"
#include "soc/efuse_reg.h"
#include "soc/soc_memory_layout.h"
#include "hal/gpio_ll.h"
#include "esp_image_format.h"
#include "bootloader_sha.h"
@ -138,7 +139,18 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)(SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t));
#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DATA_HIGH - sizeof(rtc_retain_mem_t))
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
#if !IS_BOOTLOADER_BUILD
/* The app needs to be told this memory is reserved, important if configured to use RTC memory as heap.
Note that keeping this macro here only works when other symbols in this file are referenced by the app, as
this feature is otherwise 100% part of the bootloader. However this seems to happen in all apps.
*/
SOC_RESERVE_MEMORY_REGION(RTC_RETAIN_MEM_ADDR, RTC_RETAIN_MEM_ADDR + sizeof(rtc_retain_mem_t), rtc_retain_mem);
#endif
static bool check_rtc_retain_mem(void)
{

View File

@ -8,6 +8,14 @@
#include "sdkconfig.h"
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#define SRAM_IRAM_START 0x4037C000
#define SRAM_DRAM_START 0x3FC7C000
#define ICACHE_SIZE 0x4000 /* ICache size is fixed to 16KB on ESP32-C3 */
@ -65,7 +73,7 @@ MEMORY
/**
* RTC fast memory (executable). Persists over deep sleep.
*/
rtc_iram_seg(RWX) : org = 0x50000000, len = 0x2000
rtc_iram_seg(RWX) : org = 0x50000000, len = 0x2000 - ESP_BOOTLOADER_RESERVE_RTC
}
#if CONFIG_ESP32C3_USE_FIXED_STATIC_RAM_SIZE

View File

@ -8,6 +8,14 @@
#include "sdkconfig.h"
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#else
#define ESP_BOOTLOADER_RESERVE_RTC 0
#endif
#define SRAM_IRAM_START 0x40370000
#define SRAM_DRAM_START 0x3FC80000
#define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START)
@ -65,7 +73,7 @@ MEMORY
/**
* RTC fast memory (executable). Persists over deep sleep.
*/
rtc_iram_seg(RWX) : org = 0x600fe000, len = 0x2000
rtc_iram_seg(RWX) : org = 0x600fe000, len = 0x2000 - ESP_BOOTLOADER_RESERVE_RTC
/**
* RTC fast memory (same block as above), viewed from data bus

View File

@ -72,6 +72,9 @@ const soc_memory_region_t soc_memory_regions[] = {
#if CONFIG_ESP32S3_DATA_CACHE_32KB
{ 0x3FCF0000, 0x8000, 0, 0}, //Level 9, DRAM
#endif
#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
{ 0x50000000, 0x2000, 4, 0}, //Fast RTC memory
#endif
};
const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t);

View File

@ -1,25 +1,35 @@
from __future__ import unicode_literals
import re
import time
import ttfw_idf
touch_wake_up_support = ['esp32']
touch_wake_up_support = ['esp32', 'esp32s2']
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
def test_examples_deep_sleep(env, extra_data):
dut = env.get_dut('deep_sleep', 'examples/system/deep_sleep')
dut.start_app()
def expect_enable_deep_sleep_touch():
dut.expect_all('Enabling timer wakeup, 20s',
re.compile(r'Touch pad #8 average: \d+, wakeup threshold set to \d+.'),
re.compile(r'Touch pad #9 average: \d+, wakeup threshold set to \d+.'),
'Enabling touch pad wakeup',
'Entering deep sleep',
timeout=10)
# different targets configure different wake pin(s)
wake_pads = {
'esp32': [8,9],
'esp32s2': [9],
}[dut.TARGET]
print('Expecting to see wakeup configured on pad(s): {}'.format(wake_pads))
expect_items = ['Enabling timer wakeup, 20s']
for pad in wake_pads:
expect_items += [re.compile(r'Touch pad #{} average: \d+, wakeup threshold set to \d+.'.format(pad))]
expect_items += ['Enabling touch pad wakeup',
'Entering deep sleep']
dut.expect_all(*expect_items, timeout=10)
def expect_enable_deep_sleep_no_touch():
dut.expect_all('Enabling timer wakeup, 20s',
@ -34,8 +44,20 @@ def test_examples_deep_sleep(env, extra_data):
dut.expect('Not a deep sleep reset', timeout=30)
expect_enable_deep_sleep()
# Check that it spent 2xxxxms in deep sleep, i.e at least 20 seconds:
dut.expect(re.compile(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms'), timeout=30)
start_sleep = time.time()
print('Waiting for wakeup...')
dut.expect('boot: ESP-IDF', timeout=30) # first output that's the same on all chips
sleep_time = time.time() - start_sleep
print('Host measured sleep time at {:.2f}s'.format(sleep_time))
assert 19 < sleep_time < 22 # note: high tolerance as measuring time on the host may have some timing skew
# This line indicates that the CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP option set in sdkconfig.defaults
# has correctly allowed skipping verification on wakeup
dut.expect('boot: Fast booting app from partition', timeout=2)
# Check that it measured 2xxxxms in deep sleep, i.e at least 20 seconds:
dut.expect(re.compile(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms'), timeout=2)
expect_enable_deep_sleep()

View File

@ -245,11 +245,13 @@ void app_main(void)
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_fsm_start();
vTaskDelay(100 / portTICK_RATE_MS);
/* read sleep touch pad value */
uint32_t touch_value;
/* set touchpad wakeup threshold */
uint32_t touch_value, wake_threshold;
touch_pad_sleep_channel_read_smooth(TOUCH_PAD_NUM9, &touch_value);
touch_pad_sleep_set_threshold(TOUCH_PAD_NUM9, touch_value * 0.1); //10%
printf("test init: touch pad [%d] slp %d, thresh %d\n",
wake_threshold = touch_value * 0.1; // wakeup when touch sensor crosses 10% of background level
touch_pad_sleep_set_threshold(TOUCH_PAD_NUM9, wake_threshold);
printf("Touch pad #%d average: %d, wakeup threshold set to %d\n",
TOUCH_PAD_NUM9, touch_value, (uint32_t)(touch_value * 0.1));
#endif
printf("Enabling touch pad wakeup\n");

View File

@ -1,12 +1,26 @@
# Generic config
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
CONFIG_EXAMPLE_ULP_TEMPERATURE_WAKEUP=n
CONFIG_EXAMPLE_EXT1_WAKEUP=n
# ESP32-specific config
CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=80
CONFIG_ESP32_ULP_COPROC_ENABLED=y
CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=512
CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
CONFIG_EXAMPLE_ULP_TEMPERATURE_WAKEUP=n
CONFIG_EXAMPLE_EXT1_WAKEUP=n
# ESP32S2-specific config
CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80=y
CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=80
CONFIG_ESP32S2_ULP_COPROC_ENABLED=y
CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=512
CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y
# ESP32C3-specific config
CONFIG_ESP32C3_DEFAULT_CPU_FREQ_80=y
CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ=80
# IDF-3090
CONFIG_ESP32C3_REV_MIN_0=y
CONFIG_ESP32C3_REV_MIN=0

View File

@ -0,0 +1,18 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_FREERTOS_UNICORE=y
## Below here should be same as these sections in sdkconfig.ci
# Generic config
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
CONFIG_EXAMPLE_ULP_TEMPERATURE_WAKEUP=n
CONFIG_EXAMPLE_EXT1_WAKEUP=n
# ESP32-specific config
CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=80
CONFIG_ESP32_ULP_COPROC_ENABLED=y
CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=512
CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y

View File

@ -22,10 +22,12 @@ Test applications are treated the same way as ESP-IDF examples, so each project
For each project in test_apps (and also examples):
* If a file `sdkconfig.ci` exists then it's built as the `default` CI config (same as if this file was named `sdkconfig.ci.default`)
* If any files `sdkconfig.ci.<CONFIG>` exist then these are built as alternative configs, with the specified `<CONFIG>` name.
* If a file `sdkconfig.ci` exists then it's built as the `default` CI config.
* If any additional files `sdkconfig.ci.<CONFIG>` exist then these are built as alternative configs, with the specified `<CONFIG>` name.
* By default, every CI configurations is built for every target SoC (an `m * n` configuration matrix). However if any `sdkconfig.ci` file contains a line of the form `CONFIG_IDF_TARGET="targetname"` then that CI config is only built for that one target.
The CI system expects to see at least a "default" config, so add `sdkconfig.ci` before adding any `sdkconfig.ci.CONFIG` files.
* By default, every CI configurations is built for every target SoC (an `m * n` configuration matrix). However if any `sdkconfig.ci.*` file contains a line of the form `CONFIG_IDF_TARGET="targetname"` then that CI config is only built for that one target. This only works in `sdkconfig.ci.CONFIG`, not in the default `sdkconfig.ci`.
* Each configuration is also built with the contents of any `sdkconfig.defaults` file or a file named `sdkconfig.defaults.<TARGET>` appended. (Same as a normal ESP-IDF project build.)
## Test Execution