Merge branch 'feature/allow_rtc_memory_for_task_stacks' into 'master'

Add RTC Fast Memory to Dynamic Memory Pool

See merge request espressif/esp-idf!8390
This commit is contained in:
Angus Gratton 2020-05-29 14:07:01 +08:00
commit 59f29cbca8
11 changed files with 80 additions and 10 deletions

View file

@ -739,6 +739,18 @@ menu "ESP32-specific"
This is possible due to handling of exceptions `LoadStoreError (3)` and `LoadStoreAlignmentError (9)`
Each unaligned read/write access will incur a penalty of maximum of 167 CPU cycles.
config ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
bool "Enable RTC fast memory for dynamic allocations"
default y
depends on FREERTOS_UNICORE
help
This config option allows to add RTC fast memory region to system heap with capability
similar to that of DRAM region but without DMA. This memory will be consumed first per
heap initialization order by early startup services and scheduler related code. Speed
wise RTC fast memory operates on APB clock and hence does not have much performance impact.
RTC fast memory is accessible to PRO cpu only and hence this is allowed for single core
configuration only for ESP32.
endmenu # ESP32-Specific
menu "Power Management"

View file

@ -498,6 +498,23 @@ menu "ESP32S2-specific"
If enabled, this disables the linking of binary libraries in the application build. Note
that after enabling this Wi-Fi/Bluetooth will not work.
config ESP32S2_RTCDATA_IN_FAST_MEM
bool "Place RTC_DATA_ATTR and RTC_RODATA_ATTR variables into RTC fast memory segment"
default n
help
This option allows to place .rtc_data and .rtc_rodata sections into
RTC fast memory segment to free the slow memory region for ULP programs.
config ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
bool "Enable RTC fast memory for dynamic allocations"
depends on !ESP32S2_MEMPROT_FEATURE
default y
help
This config option allows to add RTC fast memory region to system heap with capability
similar to that of DRAM region but without DMA. This memory will be consumed first per
heap initialization order by early startup services and scheduler related code. Speed
wise RTC fast memory operates on APB clock and hence does not have much performance impact.
endmenu # ESP32S2-Specific
menu "Power Management"

View file

@ -96,7 +96,7 @@ _data_seg_org = ORIGIN(rtc_data_seg);
When the option is not defined then use slow memory segment
else the data will be placed in fast memory segment
TODO: check whether the rtc_data_location is correct for esp32s2 - IDF-761 */
#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
#ifndef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM
REGION_ALIAS("rtc_data_location", rtc_slow_seg );
#else
REGION_ALIAS("rtc_data_location", rtc_data_seg );

View file

@ -46,7 +46,7 @@ SECTIONS
named rtc_wake_stub*.c and the data marked with
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option.
*/
.rtc.data :
{
@ -75,7 +75,7 @@ SECTIONS
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.
CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option.
*/
.rtc_noinit (NOLOAD):
{

View file

@ -448,6 +448,10 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
input_needs_realloc = true;
}
if (!esp_ptr_dma_ext_capable(output) && !esp_ptr_dma_capable(output)) {
output_needs_realloc = true;
}
/* If either input or output is unaccessible to the DMA then they need to be reallocated */
if (input_needs_realloc || output_needs_realloc) {
return esp_aes_process_dma_ext_ram(ctx, input, output, len, stream_out, input_needs_realloc, output_needs_realloc);

View file

@ -176,6 +176,12 @@ inline static bool IRAM_ATTR esp_ptr_byte_accessible(const void *p)
intptr_t ip = (intptr_t) p;
bool r;
r = (ip >= SOC_BYTE_ACCESSIBLE_LOW && ip < SOC_BYTE_ACCESSIBLE_HIGH);
#if CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
/* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence
* for single core configuration (where it gets added to system heap) following
* additional check is required */
r |= (ip >= SOC_RTC_DRAM_LOW && ip < SOC_RTC_DRAM_HIGH);
#endif
#if CONFIG_SPIRAM
#if CONFIG_SPIRAM_SIZE != -1 // Fixed size, can be more accurate
r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE));
@ -190,6 +196,12 @@ inline static bool IRAM_ATTR esp_ptr_internal(const void *p) {
bool r;
r = ((intptr_t)p >= SOC_MEM_INTERNAL_LOW && (intptr_t)p < SOC_MEM_INTERNAL_HIGH);
r |= ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH);
#if CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
/* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence
* for single core configuration (where it gets added to system heap) following
* additional check is required */
r |= ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH);
#endif
return r;
}

View file

@ -66,10 +66,10 @@ const soc_memory_type_desc_t soc_memory_types[] = {
{ "PID5DRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
{ "PID6DRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
{ "PID7DRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
#ifdef CONFIG_SPIRAM
//Type 15: SPI SRAM data
{ "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
#endif
//Type 16: RTC Fast RAM
{ "RTCRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT, 0 }, false, false},
};
const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t);
@ -88,6 +88,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th
from low to high start address.
*/
const soc_memory_region_t soc_memory_regions[] = {
#ifdef CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
{ SOC_RTC_DRAM_LOW, 0x2000, 16, 0}, //RTC Fast Memory
#endif
#ifdef CONFIG_SPIRAM
{ SOC_EXTRAM_DATA_LOW, RESERVE_SPIRAM_SIZE, 15, 0}, //SPI SRAM, if available
#endif
@ -183,7 +186,7 @@ SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace me
SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_LOW + RESERVE_SPIRAM_SIZE, spi_ram); //SPI RAM gets added later if needed, in spiram.c; reserve it for now
#endif
extern int _data_start, _heap_start, _iram_start, _iram_end;
extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end;
// Static data region. DRAM used by data+bss and possibly rodata
SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
@ -191,5 +194,13 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d
// ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part
SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
// RTC Fast RAM region
#ifdef CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP
#ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data);
#else
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data);
#endif
#endif
#endif /* BOOTLOADER_BUILD */

View file

@ -51,6 +51,8 @@ const soc_memory_type_desc_t soc_memory_types[] = {
//Type 4: SPI SRAM data
//TODO, in fact, part of them support EDMA, to be supported.
{ "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
//Type 5: RTC Fast RAM
{ "RTCRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT, 0 }, false, false},
};
#ifdef CONFIG_ESP32S2_MEMPROT_FEATURE
@ -68,6 +70,9 @@ Because of requirements in the coalescing code which merges adjacent regions, th
from low to high start address.
*/
const soc_memory_region_t soc_memory_regions[] = {
#ifdef CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
{ SOC_RTC_DRAM_LOW, 0x2000, 5, 0}, //RTC Fast Memory
#endif
#ifdef CONFIG_SPIRAM
{ SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW, 4, 0}, //SPI SRAM, if available
#endif
@ -115,7 +120,7 @@ const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_mem
extern int _dram0_rtos_reserved_start;
extern int _data_start, _heap_start, _iram_start, _iram_end;
extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end;
/* Reserved memory regions
@ -141,4 +146,13 @@ SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_dat
SOC_RESERVE_MEMORY_REGION(0x3fffc000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM, 0x3fffc000, trace_mem);
#endif
// RTC Fast RAM region
#ifdef CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP
#ifdef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data);
#else
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data);
#endif
#endif
#endif // BOOTLOADER_BUILD

View file

@ -68,7 +68,7 @@ static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t c
reserved[i].start, reserved[i].end);
reserved[i].start = reserved[i].start & ~3; /* expand all reserved areas to word boundaries */
reserved[i].end = (reserved[i].end + 3) & ~3;
assert(reserved[i].start < reserved[i].end);
assert(reserved[i].start <= reserved[i].end);
if (i < count - 1) {
assert(reserved[i + 1].start > reserved[i].start);
if (reserved[i].end > reserved[i + 1].start) {

View file

@ -3,4 +3,4 @@ CONFIG_IDF_TARGET="esp32s2"
TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_timer driver heap pthread soc spi_flash vfs
CONFIG_MEMMAP_SMP=n
CONFIG_FREERTOS_UNICORE=y
CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y

View file

@ -3,4 +3,4 @@ CONFIG_IDF_TARGET="esp32s2"
TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs test_utils
CONFIG_MEMMAP_SMP=n
CONFIG_FREERTOS_UNICORE=y
CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y