Skip to content

Commit

Permalink
soc: espressif: keep RTC data after deep-sleep
Browse files Browse the repository at this point in the history
This PR includes changes in all Espressif's SoCs to enable
keeping data in RTC memory after deep-sleep.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
  • Loading branch information
sylvioalves authored and kartben committed Jan 10, 2025
1 parent 34bc4c3 commit 5d05e28
Show file tree
Hide file tree
Showing 7 changed files with 378 additions and 217 deletions.
32 changes: 19 additions & 13 deletions soc/espressif/common/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,15 @@
#define IS_IRAM(addr) (addr >= SOC_IRAM_LOW && addr < SOC_IRAM_HIGH)
#define IS_IROM(addr) (addr >= SOC_IROM_LOW && addr < SOC_IROM_HIGH)
#define IS_DROM(addr) (addr >= SOC_DROM_LOW && addr < SOC_DROM_HIGH)
#define IS_SRAM(addr) (IS_IRAM(addr) || IS_DRAM(addr))
#define IS_MMAP(addr) (IS_IROM(addr) || IS_DROM(addr))
#define IS_NONE(addr) \
(!IS_IROM(addr) && !IS_DROM(addr) && !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr))
#ifdef SOC_RTC_MEM_SUPPORTED
#define IS_RTC(addr) (addr >= SOC_RTC_DRAM_LOW && addr < SOC_RTC_DRAM_HIGH)
#else
#define IS_RTC(addr) 0
#endif
#define IS_SRAM(addr) (IS_IRAM(addr) || IS_DRAM(addr))
#define IS_MMAP(addr) (IS_IROM(addr) || IS_DROM(addr))
#define IS_NONE(addr) (!IS_IROM(addr) && !IS_DROM(addr) \
&& !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr) && !IS_RTC(addr))

#define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used))

Expand All @@ -78,6 +83,7 @@ static uint32_t _app_irom_size = (uint32_t)&_image_irom_size;
static uint32_t _app_drom_start =
(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_drom_start);
static uint32_t _app_drom_size = (uint32_t)&_image_drom_size;

#endif

static uint32_t _app_irom_vaddr = ((uint32_t)&_image_irom_vaddr);
Expand Down Expand Up @@ -122,14 +128,13 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t
}

ESP_EARLY_LOGI(TAG, "%s: lma 0x%08x vma 0x%08x len 0x%-6x (%u)",
IS_NONE(segment_hdr.load_addr) ? "???"
: IS_MMAP(segment_hdr.load_addr)
? IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP"
: IS_PADD(segment_hdr.load_addr) ? "padd"
: IS_DRAM(segment_hdr.load_addr) ? "DRAM"
: "IRAM",
offset + sizeof(esp_image_segment_header_t), segment_hdr.load_addr,
segment_hdr.data_len, segment_hdr.data_len);
IS_NONE(segment_hdr.load_addr) ? "???" :
IS_MMAP(segment_hdr.load_addr) ?
IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP" :
IS_DRAM(segment_hdr.load_addr) ? "DRAM" :
IS_RTC(segment_hdr.load_addr) ? "RTC" : "IRAM",
offset + sizeof(esp_image_segment_header_t),
segment_hdr.load_addr, segment_hdr.data_len, segment_hdr.data_len);

/* Fix drom and irom produced be the linker, as it could
* be invalidated by the elf2image and flash load offset
Expand All @@ -142,9 +147,10 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t
app_irom_start = offset + sizeof(esp_image_segment_header_t);
app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK;
}
if (IS_SRAM(segment_hdr.load_addr)) {
if (IS_SRAM(segment_hdr.load_addr) || IS_RTC(segment_hdr.load_addr)) {
ram_segments++;
}

offset += sizeof(esp_image_segment_header_t) + segment_hdr.data_len;

if (ram_segments == bootloader_image_hdr.segment_count && !checksum) {
Expand Down
111 changes: 89 additions & 22 deletions soc/espressif/esp32/default.ld
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ MEMORY
{
#ifdef CONFIG_BOOTLOADER_MCUBOOT
mcuboot_hdr (R): org = 0x0, len = 0x20
metadata (R): org = 0x20, len = 0x20
FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40
metadata (R): org = 0x20, len = 0x60
FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80
#else
/* Make safety margin in the FLASH memory size so the
* (esp_img_header + (n*esp_seg_headers)) would fit */
Expand All @@ -69,7 +69,19 @@ MEMORY
drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN

rtc_iram_seg(RWX): org = 0x400c0000, len = 0x2000
rtc_slow_seg(RW): org = 0x50000000, len = 0x1000
rtc_slow_seg(RW): org = 0x50000000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM
rtc_data_seg(RW): org = 0x3ff80000, len = 0x2000

/* We reduced the size of rtc_slow_seg by CONFIG_RESERVE_RTC_MEM value.
It reserves the amount of RTC slow memory that we use for this memory segment.
This segment is intended for keeping rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files).
The aim of this is to keep data that will not be moved around and have a fixed address.
org = 0x50000000 + 0x2000 - CONFIG_RESERVE_RTC_MEM
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
rtc_slow_reserved_seg(RW): org = 0x50000000 + 0x2000 - CONFIG_RESERVE_RTC_MEM,
len = CONFIG_RESERVE_RTC_MEM
#endif

#ifdef CONFIG_ESP_SPIRAM
ext_ram_seg(RW): org = 0x3f800000, len = CONFIG_ESP_SPIRAM_SIZE
Expand Down Expand Up @@ -126,6 +138,25 @@ SECTIONS
LONG(ADDR(.dram0.data))
LONG(LOADADDR(.dram0.data))
LONG(LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - LOADADDR(.dram0.data))

/* RTC_TEXT metadata:
* 8. Destination address (VMA) for RTC_TEXT region
* 9. Flash offset (LMA) for start of RTC_TEXT region
* 10. Size of RTC region
*/
LONG(ADDR(.rtc.text))
LONG(LOADADDR(.rtc.text))
LONG(SIZEOF(.rtc.text))

/* RTC_DATA metadata:
* 11. Destination address (VMA) for RTC_DATA region
* 12. Flash offset (LMA) for start of RTC_DATA region
* 13. Size of RTC region
*/
LONG(ADDR(.rtc.data))
LONG(LOADADDR(.rtc.data))
LONG(SIZEOF(.rtc.data))

} > metadata
#endif /* CONFIG_BOOTLOADER_MCUBOOT */

Expand All @@ -137,54 +168,90 @@ SECTIONS

/* --- RTC BEGIN --- */

/* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
. = ALIGN(4);
*(.rtc.literal .rtc.text)
*rtc_wake_stub*.o(.literal .text .literal.* .text.*)
*(.rtc.literal .rtc.literal.*)
*(.rtc.text .rtc.text.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)

/* RTC slow memory holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c
*/
/*
This section is required to skip rtc.text area because rtc_iram_seg and
rtc_data_seg reflect the same address space on different buses.
*/
.rtc.dummy :
{
. = SIZEOF(.rtc.text);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)

/* This section located in RTC FAST Memory area.
It holds data marked with RTC_FAST_ATTR attribute.
See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
. = ALIGN(4);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)

/* RTC data section holds RTC wake stub
data/rodata, including from any source file
named rtc_wake_stub*.c and the data marked with
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
. = ALIGN(4);
_rtc_data_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*)
_rtc_data_end = ABSOLUTE(.);
*(.rtc.data .rtc.data.*)
*(.rtc.rodata .rtc.rodata.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)

/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.o(.bss .bss.*)
*rtc_wake_stub*.o(COMMON)
*(.rtc.bss .rtc.bss.*)
_rtc_bss_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_slow_seg)

.rtc_noinit (NOLOAD) :
{
. = ALIGN(4);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
} GROUP_LINK_IN(rtc_slow_seg)

/* 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.
*/
.rtc.force_slow :
{
. = ALIGN(4);
_rtc_force_slow_start = ABSOLUTE(.);
*(.rtc.force_slow .rtc.force_slow.*)
. = ALIGN(4) ;
_rtc_force_slow_end = ABSOLUTE(.);
} > rtc_slow_seg
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)

/* Get size of rtc slow data */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);

/**
* This section holds RTC SLOW data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep sleep.
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
.rtc_slow_reserved (NOLOAD) :
{
. = ALIGN(4);
_rtc_slow_reserved_start = ABSOLUTE(.);
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
_rtc_slow_reserved_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_slow_reserved_seg)
#endif

/* --- RTC END --- */

/* --- IRAM BEGIN --- */
Expand Down
Loading

0 comments on commit 5d05e28

Please sign in to comment.