soc: espressif: keep RTC data after deep-sleep

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>
This commit is contained in:
Sylvio Alves 2025-01-07 11:49:09 -03:00 committed by Benjamin Cabé
commit 5d05e28fce
7 changed files with 376 additions and 215 deletions

View file

@ -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))
@ -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);
@ -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
@ -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) {

View file

@ -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 */
@ -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
@ -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 */
@ -137,38 +168,62 @@ 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.
@ -176,15 +231,27 @@ SECTIONS
.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 --- */

View file

@ -59,8 +59,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 */
@ -73,19 +73,24 @@ MEMORY
irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN
drom0_0_seg (R): org = DROM_SEG_ORG, len = DROM_SEG_LEN
rtc_iram_seg(RWX): org = 0x50000000, len = 0x2000
rtc_iram_seg(RWX): org = 0x50000000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM
/* We reduced the size of rtc_iram_seg by CONFIG_RESERVE_RTC_MEM value.
It reserves the amount of RTC fast memory that we use for this memory segment.
This segment is intended for keeping:
- (lower addr) 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.
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
rtc_reserved_seg(RW): org = 0x50000000 + 0x2000 - CONFIG_RESERVE_RTC_MEM,
len = CONFIG_RESERVE_RTC_MEM
#endif
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
#endif
}
/* The line below defines location alias for .rtc.data section
* As C3 only has RTC fast memory, this is not configurable like
* on other targets.
*/
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg);
/* Default entry point: */
ENTRY(CONFIG_KERNEL_ENTRY)
@ -132,17 +137,27 @@ SECTIONS
LONG(ADDR(.dram0.data))
LONG(LOADADDR(.dram0.data))
LONG(LOADADDR(.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 */
iram_vma = ADDR(.iram0.text);
iram_lma = LOADADDR(.iram0.text);
iram_size_field = LOADADDR(.iram0.data) - LOADADDR(.iram0.text);
dram_vma = ADDR(.dram0.data);
dram_lma = LOADADDR(.dram0.data);
dram_size_field = LOADADDR(.dram0.end) - LOADADDR(.dram0.data);
#include <zephyr/linker/rel-sections.ld>
#ifdef CONFIG_LLEXT
@ -151,38 +166,61 @@ SECTIONS
/* --- START OF RTC --- */
/* RTC fast memory holds RTC wake stub code */
.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)
/* This section is required to skip rtc.text area because the text and
* data segments reflect the same address space on different buses.
/**
* 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.dummy (NOLOAD):
.rtc.force_fast :
{
. = SIZEOF(.rtc.text);
} GROUP_LINK_IN(rtc_iram_seg)
. = ALIGN(4);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
/**
* RTC data section holds data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
* See the file "esp_attr.h" for more information.
*/
.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_iram_seg, ROMABLE_REGION)
.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_iram_seg)
/**
* 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.
*/
.rtc_noinit (NOLOAD) :
{
. = ALIGN(4);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4);
} GROUP_LINK_IN(rtc_iram_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.
@ -190,15 +228,28 @@ SECTIONS
.rtc.force_slow :
{
. = ALIGN(4);
_rtc_force_slow_start = ABSOLUTE(.);
*(.rtc.force_slow .rtc.force_slow.*)
. = ALIGN(4) ;
. = ALIGN(4);
_rtc_force_slow_end = ABSOLUTE(.);
} > rtc_slow_seg
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
/* Get size of rtc slow data */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);
/**
* This section holds RTC 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_reserved (NOLOAD) :
{
. = ALIGN(4);
_rtc_reserved_start = ABSOLUTE(.);
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
_rtc_reserved_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_reserved_seg)
#endif
/* --- END OF RTC --- */
/* --- START OF IRAM --- */

View file

@ -48,16 +48,13 @@ user_sram_size = (user_sram_end - user_sram_org);
#undef SECTION_PROLOGUE
#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE
/* TODO: add RTC support */
#define RESERVE_RTC_MEM 0
/* Global symbols required for espressif hal build */
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 */
@ -70,10 +67,19 @@ MEMORY
drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN
lp_ram_seg(RW): org = LPSRAM_IRAM_START,
len = 0x2000 - RESERVE_RTC_MEM
len = 0x4000 - CONFIG_RESERVE_RTC_MEM
lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x2000 - RESERVE_RTC_MEM,
len = RESERVE_RTC_MEM
/* We reduced the size of lp_ram_seg by CONFIG_RESERVE_RTC_MEM value.
It reserves the amount of LP memory that we use for this memory segment.
This segment is intended for keeping:
- (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files).
- (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on).
The aim of this is to keep data that will not be moved around and have a fixed address.
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x4000 - CONFIG_RESERVE_RTC_MEM,
len = CONFIG_RESERVE_RTC_MEM
#endif
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
@ -90,7 +96,6 @@ REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
/* Default entry point: */
ENTRY(CONFIG_KERNEL_ENTRY)
@ -133,6 +138,26 @@ SECTIONS
LONG(ADDR(.dram0.data))
LONG(LOADADDR(.dram0.data))
LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data))
/* LP_IRAM metadata:
* 8. Destination address (VMA) for LP_IRAM region
* 9. Flash offset (LMA) for start of LP_IRAM region
* 10. Size of RTC region
*/
LONG(ADDR(.rtc.text))
LONG(LOADADDR(.rtc.text))
LONG(SIZEOF(.rtc.text))
/* LP_DATA metadata:
* 11. Destination address (VMA) for LP_DATA region
* 12. Flash offset (LMA) for start of LP_DATA region
* 13. Size of RTC region
*/
LONG(ADDR(.rtc.data))
LONG(LOADADDR(.rtc.data))
LONG(SIZEOF(.rtc.data))
} > metadata
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
@ -150,12 +175,10 @@ SECTIONS
_rtc_fast_start = ABSOLUTE(.);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.entry.text)
*(.rtc.literal .rtc.text)
*rtc_wake_stub*.o(.literal .text .literal.* .text.*)
*(.rtc.literal .rtc.literal.* .rtc.text .rtc.text.*)
. = ALIGN(4);
_rtc_text_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
/* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
@ -167,9 +190,9 @@ SECTIONS
_rtc_force_fast_start = ABSOLUTE(.);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4) ;
. = ALIGN(4);
_rtc_force_fast_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
/* RTC data section holds data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
@ -177,34 +200,31 @@ SECTIONS
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*(.rtc.data .rtc.data.*)
*(.rtc.rodata .rtc.rodata.*)
_rtc_data_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*(.rtc.bss .rtc.bss.*)
_rtc_bss_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_iram_seg)
} GROUP_LINK_IN(lp_ram_seg)
/* 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.
*/
.rtc_noinit (NOLOAD):
.rtc_noinit (NOLOAD) :
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_slow_seg)
} GROUP_LINK_IN(lp_ram_seg)
/* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
@ -217,24 +237,21 @@ SECTIONS
*(.rtc.force_slow .rtc.force_slow.*)
. = ALIGN(4);
_rtc_force_slow_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep sleep.
*/
.rtc_reserved (NOLOAD):
#if (CONFIG_RESERVE_RTC_MEM > 0)
.rtc_reserved (NOLOAD) :
{
. = ALIGN(4);
_rtc_reserved_start = ABSOLUTE(.);
/* New data can only be added here to ensure existing data are not moved.
Because data have adhered to the end of the segment and code is relied on it.
>> put new data here << */
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_reserved_seg)
} GROUP_LINK_IN(lp_reserved_seg)
#endif
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);

View file

@ -55,14 +55,12 @@ user_dram_seg_len = user_sram_size;
#undef SECTION_PROLOGUE
#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE
#define RESERVE_RTC_MEM 0
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
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 */
@ -75,18 +73,22 @@ MEMORY
irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN
drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN
rtc_iram_seg(RWX): org = 0x40070000, len = 0x2000 - RESERVE_RTC_MEM
rtc_iram_seg(RWX): org = 0x40070000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM
rtc_slow_seg(RW): org = 0x50000000, len = 0x2000
/* RTC fast memory (same block as above, rtc_iram_seg), viewed from data bus */
rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 - RESERVE_RTC_MEM
/* We reduced the size of rtc_data_seg and rtc_iram_seg by RESERVE_RTC_MEM value.
* It reserves the amount of RTC fast memory that we use for this memory segment.
* This segment is intended for keeping:
* - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files).
* - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on).
* The aim of this is to keep data that will not be moved around and have a fixed address.
*/
rtc_reserved_seg(RW) : org = 0x3ff9e000 + 0x2000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM
rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM
/* We reduced the size of rtc_data_seg and rtc_iram_seg by CONFIG_RESERVE_RTC_MEM value.
It reserves the amount of RTC fast memory that we use for this memory segment.
This segment is intended for keeping:
- (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files).
- (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on).
The aim of this is to keep data that will not be moved around and have a fixed address.
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
rtc_reserved_seg(RW): org = 0x3ff9e000 + 0x2000 - CONFIG_RESERVE_RTC_MEM,
len = CONFIG_RESERVE_RTC_MEM
#endif
#ifdef CONFIG_ESP_SPIRAM
ext_data_ram_seg(RW): org = 0x3f800000, len = CONFIG_ESP_SPIRAM_SIZE /* OR 0x780000 */
#endif /* CONFIG_ESP_SPIRAM */
@ -142,6 +144,25 @@ SECTIONS
LONG(ADDR(.dram0.data))
LONG(LOADADDR(.dram0.data))
LONG(LOADADDR(.dram0.data_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 */
@ -154,128 +175,90 @@ SECTIONS
/* --- START OF RTC --- */
/* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
_rtc_text_start = ABSOLUTE(.);
. = ALIGN(4);
_rtc_code_start = .;
/* mapping[rtc_text] */
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
_rtc_code_end = .;
/* possibly align + add 16B for CPU dummy speculative instr. fetch */
. = ((_rtc_code_end - _rtc_code_start) == 0) ? ALIGN(0) : ALIGN(4) + 16;
_rtc_text_end = ABSOLUTE(.);
*(.rtc.literal .rtc.literal.*)
*(.rtc.text .rtc.text.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
/*
* This section is required to skip rtc.text area because rtc_iram_seg and
* rtc_data_seg are reflect the same address space on different buses.
*/
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 :
{
_rtc_dummy_start = ABSOLUTE(.);
_rtc_fast_start = ABSOLUTE(.);
. = SIZEOF(.rtc.text);
_rtc_dummy_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
} 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.
*/
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_start = ABSOLUTE(.);
/* mapping[rtc_force_fast] */
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4) ;
_rtc_force_fast_end = ABSOLUTE(.);
} > rtc_data_seg
. = 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.
*/
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.data.*)
*(.rtc.rodata .rtc.rodata.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* mapping[rtc_data] */
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.*)
_rtc_data_end = ABSOLUTE(.);
} > rtc_data_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.*)
*rtc_wake_stub*.*(COMMON)
/* mapping[rtc_bss] */
*(.rtc.bss .rtc.bss.*)
_rtc_bss_end = ABSOLUTE(.);
} > rtc_data_seg
} GROUP_LINK_IN(rtc_slow_seg)
/* 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.
*/
.rtc_noinit (NOLOAD):
.rtc_noinit (NOLOAD) :
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} > rtc_data_seg
} 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.
* 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) ;
. = ALIGN(4);
_rtc_force_slow_end = ABSOLUTE(.);
} > rtc_slow_seg
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
/* Get size of rtc slow data */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep sleep.
*/
.rtc_reserved (NOLOAD):
#if (CONFIG_RESERVE_RTC_MEM > 0)
.rtc_reserved (NOLOAD) :
{
. = ALIGN(4);
_rtc_reserved_start = ABSOLUTE(.);
/* New data can only be added here to ensure existing data are not moved.
Because data have adhered to the end of the segment and code is relied on it.
>> put new data here << */
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
/* Get size of rtc slow data */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);
} GROUP_LINK_IN(rtc_reserved_seg)
#endif
/* --- END OF RTC --- */
@ -790,6 +773,7 @@ SECTIONS
.ext_ram_noinit (NOLOAD) :
{
_ext_ram_noinit_start = ABSOLUTE(.);
#ifdef CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM
*libdrivers__wifi.a:(.noinit .noinit.*)
*libsubsys__net__l2__ethernet.a:(.noinit .noinit.*)
@ -797,6 +781,7 @@ SECTIONS
*libsubsys__net__ip.a:(.noinit .noinit.*)
*libsubsys__net.a:(.noinit .noinit.*)
#endif /* CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM */
_ext_ram_noinit_end = ABSOLUTE(.);
_spiram_heap_start = ABSOLUTE(.);
. += CONFIG_ESP_SPIRAM_HEAP_SIZE;

View file

@ -50,8 +50,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 */
@ -76,11 +76,19 @@ 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 - CONFIG_RESERVE_RTC_MEM
/* RTC fast memory (same block as above), viewed from data bus
*/
rtc_data_seg(RW): org = 0x600fe000, len = 0x2000
/* We reduced the size of rtc_iram_seg by CONFIG_RESERVE_RTC_MEM value.
It reserves the amount of RTC fast memory that we use for this memory segment.
This segment is intended for keeping:
- (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files).
- (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on).
The aim of this is to keep data that will not be moved around and have a fixed address.
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
rtc_reserved_seg(RW): org = 0x600fe000 + 0x2000 - CONFIG_RESERVE_RTC_MEM,
len = CONFIG_RESERVE_RTC_MEM
#endif
/* RTC slow memory (data accessible). Persists over deep sleep.
*/
@ -140,6 +148,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 */
@ -156,11 +183,13 @@ SECTIONS
.rtc.text :
{
. = ALIGN(4);
_rtc_fast_start = ABSOLUTE(.);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.entry.literal .rtc.text)
_rtc_fast_start = ABSOLUTE(.);
*(.rtc.literal .rtc.literal.*)
*(.rtc.text .rtc.text.*)
*(.rtc.entry.literal)
*(.rtc.entry.text)
_rtc_text_end = ABSOLUTE(.);
. = ALIGN(4);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
/* This section located in RTC FAST Memory area.
@ -171,30 +200,27 @@ SECTIONS
{
. = ALIGN(4);
_rtc_force_fast_start = ABSOLUTE(.);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4) ;
. = ALIGN(4);
_rtc_force_fast_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* RTC data section holds data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
. = ALIGN(4);
_rtc_data_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*(.rtc.data .rtc.data.*)
*(.rtc.rodata .rtc.rodata.*)
_rtc_data_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*(.rtc.bss .rtc.bss.*)
_rtc_bss_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_slow_seg)
@ -203,13 +229,11 @@ SECTIONS
* 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):
.rtc_noinit (NOLOAD) :
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_slow_seg)
/* This section located in RTC SLOW Memory area.
@ -225,13 +249,24 @@ SECTIONS
_rtc_force_slow_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/**
* This section holds RTC 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_reserved (NOLOAD) :
{
. = ALIGN(4);
_rtc_reserved_start = ABSOLUTE(.);
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
_rtc_reserved_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_reserved_seg)
#endif
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);
_rtc_fast_length = (_rtc_force_fast_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), "RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), "RTC_FAST segment data does not fit.")
/* --- END OF RTC --- */
/* --- START OF IRAM --- */