From fb47f094d36a9dd2244d2522079e078a10acafc3 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Fri, 10 Jul 2020 08:42:01 +0200 Subject: [PATCH] cpu/esp32: support multiple heaps for newlib Several unsused DRAM sections are added to the heap. --- cpu/esp32/include/cpu_conf.h | 5 +++++ cpu/esp32/ld/esp32.common.ld | 38 ++++++++++++++++++++++++++++++++---- cpu/esp_common/syscalls.c | 21 +++++++++++++++++++- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/cpu/esp32/include/cpu_conf.h b/cpu/esp32/include/cpu_conf.h index 89038996d2..6037d499f1 100644 --- a/cpu/esp32/include/cpu_conf.h +++ b/cpu/esp32/include/cpu_conf.h @@ -51,6 +51,11 @@ extern "C" { */ #define PRINTF_BUFSIZ 256 +/** + * @brief Remaining parts of the various DRAM sections can be used as heap. + */ +#define NUM_HEAPS (4) + #ifdef __cplusplus } #endif diff --git a/cpu/esp32/ld/esp32.common.ld b/cpu/esp32/ld/esp32.common.ld index 0b6f4db88a..3fb975dc97 100644 --- a/cpu/esp32/ld/esp32.common.ld +++ b/cpu/esp32/ld/esp32.common.ld @@ -97,6 +97,13 @@ SECTIONS _iram_start = ABSOLUTE(0); } > iram0_0_seg + /* If Bluetooth is not used, this DRAM section can be used as heap */ + . = _data_start_btdm; /* 0x3ffae6e0 */ + . = ALIGN (4); + _sheap1 = ABSOLUTE(.); + . = 0x3ffb0000; + _eheap1 = ABSOLUTE(.); + .iram0.text : { /* Code marked as running out of IRAM */ @@ -131,8 +138,21 @@ SECTIONS INCLUDE esp32.spiram.rom-functions-iram.ld _iram_text_end = ABSOLUTE(.); + + /* IRAM can't be used as heap since it only allows 32-bit aligned access */ + /* + . = ALIGN (4); + _sheap4 = ABSOLUTE(.); + */ } > iram0_0_seg + /* IRAM can't be used as heap since it only allows 32-bit aligned access */ + /* + . = 0x400a0000; + _eheap4 = ABSOLUTE(.); + */ + + /* Starts at 0x3ffb000 if Bluetooth is not enabled, 0x3ffc0000 otherwise */ .dram0.data : { _data_start = ABSOLUTE(.); @@ -201,13 +221,23 @@ SECTIONS _sheap = ABSOLUTE(.); } >dram0_0_seg - /* TODO HEAP handling when BT is used - ETS system memory seems to start at 0x3FFE0000 if BT is not used. - This is the top of the heap for the app */ - . = 0x3FFE0000; + /* Reserved ROM/ETS data start at 0x3ffe000. */ + . = 0x3ffe0000; _heap_top = ABSOLUTE(.); _eheap = ABSOLUTE(.); + /* Reserved ROM/ETS data region for PRO CPU: 0x3ffe0000 ... 0x3ffe440 */ + . = 0x3ffe0440; + _sheap2 = ABSOLUTE(.); + . = 0x3ffe4000; + _eheap2 = ABSOLUTE(.); + + /* Reserved ROM/ETS data region for APP CPU: 0x3ffe4000 ... 0x3ffe4350 */ + . = 0x3ffe4350; + _sheap3 = ABSOLUTE(.); + . = 0x40000000; + _eheap3 = ABSOLUTE(.); + .flash.rodata : { _rodata_start = ABSOLUTE(.); diff --git a/cpu/esp_common/syscalls.c b/cpu/esp_common/syscalls.c index 6674c6e11b..5d520ed0e6 100644 --- a/cpu/esp_common/syscalls.c +++ b/cpu/esp_common/syscalls.c @@ -326,10 +326,29 @@ void heap_caps_init(void) extern uint8_t _eheap; /* end of heap (defined in ld script) */ extern uint8_t _sheap; /* start of heap (defined in ld script) */ +extern uint8_t _sheap1; +extern uint8_t _eheap1; + +extern uint8_t _sheap2; +extern uint8_t _eheap2; + +extern uint8_t _sheap3; +extern uint8_t _eheap3; + unsigned int IRAM_ATTR get_free_heap_size(void) { struct mallinfo minfo = mallinfo(); - return &_eheap - &_sheap - minfo.uordblks; + unsigned int heap_size = &_eheap - &_sheap; +#if NUM_HEAPS > 1 + heap_size += &_eheap1 - &_sheap1; +#endif +#if NUM_HEAPS > 2 + heap_size += &_eheap2 - &_sheap2; +#endif +#if NUM_HEAPS > 3 + heap_size += &_eheap3 - &_sheap3; +#endif + return heap_size - minfo.uordblks; } /* alias for compatibility with espressif/wifi_libs */