Skip to content

Commit 7356cd1

Browse files
authored
Heap init code improvements and updates (#8458)
* Heap init code improvements and updates Moved secondary heap init code to flash. External -24 IRAM, +32 IROM IRAM -76 IRAM, +64 IROM General updates to umm_init call path and DEFINES to better align with upstream. Name changes: UMM_INIT_HEAP with UMM_CHECK_INITIALIZED, umm_init_stage_2 with _umm_init_heap, and umm_init_common with umm_init_heap. Add file umm_cfgport.h to hold port-specific values. Stay focused on heap initialization only move-related defines. Improved comments. Created a wrapper function for running pre-SDK code from flash. Updated hwdt_app_entry to use it. Update umm_init with option to run from ICACHE. Added build define UMM_INIT_USE_ICACHE to move umm_init call path to flash. When used frees up 160 bytes of IRAM at a cost of 208 bytes of IROM Defaults to no change, umm_init call path will be in IRAM. * Changed default to use IROM for umm_init() and option to revert back to UMM_INIT_USE_IRAM.
1 parent d7c3d7b commit 7356cd1

12 files changed

+290
-166
lines changed

cores/esp8266/core_esp8266_app_entry_noextra4k.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@ extern "C" void app_entry_redefinable(void)
3939
{
4040
g_pcont = &g_cont;
4141

42+
#ifdef UMM_INIT_USE_IRAM
43+
/*
44+
* Legacy option: the umm_init() call path must reside in IRAM.
45+
*/
4246
umm_init();
47+
#else
48+
/*
49+
* Instruction cache is enabled/disabled around running umm_init().
50+
* Allows the use of IROM (flash) to store umm_init().
51+
*/
52+
mmu_wrap_irom_fn(umm_init);
53+
#endif
54+
4355
/* Call the entry point of the SDK code. */
4456
call_user_start();
4557
}

cores/esp8266/core_esp8266_main.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,12 @@ extern "C" void app_entry_redefinable(void)
365365

366366
/* Doing umm_init just once before starting the SDK, allowed us to remove
367367
test and init calls at each malloc API entry point, saving IRAM. */
368+
#ifdef UMM_INIT_USE_IRAM
368369
umm_init();
370+
#else
371+
// umm_init() is in IROM
372+
mmu_wrap_irom_fn(umm_init);
373+
#endif
369374
/* Call the entry point of the SDK code. */
370375
call_user_start();
371376
}

cores/esp8266/hwdt_app_entry.cpp

+30-32
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
#include <esp8266_peri.h>
276276
#include <uart.h>
277277
#include <pgmspace.h>
278+
#include "mmu_iram.h"
278279

279280
extern "C" {
280281
#include <user_interface.h>
@@ -1007,6 +1008,18 @@ STATIC void IRAM_MAYBE handle_hwdt(void) {
10071008
#endif
10081009
}
10091010

1011+
#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM)
1012+
static void printSanityCheck() {
1013+
ETS_PRINTF("\n\nsys_stack_first: %p\n", sys_stack_first);
1014+
ETS_PRINTF( "CONT_STACK: %p\n", CONT_STACK);
1015+
ETS_PRINTF( "g_pcont: %p\n", g_pcont);
1016+
ETS_PRINTF( "ROM_STACK: %p\n", ROM_STACK);
1017+
ETS_PRINTF( "get_noextra4k_g_pcont(): %p\n", get_noextra4k_g_pcont());
1018+
ETS_PRINTF( "g_rom_stack: %p\n", g_rom_stack);
1019+
ETS_PRINTF( "g_rom_stack_A16_sz: 0x%08X\n\n", g_rom_stack_A16_sz);
1020+
}
1021+
#endif //DEBUG_ESP_HWDT_DEV_DEBUG
1022+
10101023
/*
10111024
* Using Cache_Read_Enable/Cache_Read_Disable to reduce IRAM usage. Moved
10121025
* strings and most functions to flash. At this phase of the startup, "C++" has
@@ -1019,34 +1032,11 @@ STATIC void IRAM_MAYBE handle_hwdt(void) {
10191032
* https://richard.burtons.org/2015/06/12/esp8266-cache_read_enable/.
10201033
* Additional insight can be gleemed from reviewing the ESP8266_RTOS_SDK.
10211034
* (eg. ../components/bootloader_support/src/bootloader_utility.c)
1035+
*
1036+
* The logic to use Cache_Read_Enable and Cache_Read_Disable has been
1037+
* generalized into a wrapper function, mmu_wrap_irom_fn, and moved to
1038+
* mmu_iram.cpp.
10221039
*/
1023-
#define ICACHE_SIZE_32 1
1024-
#define ICACHE_SIZE_16 0
1025-
1026-
extern "C" void Cache_Read_Disable(void);
1027-
extern "C" void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v);
1028-
1029-
#ifndef USE_IRAM
1030-
static void IRAM_ATTR __attribute__((noinline)) handle_hwdt_icache() __attribute__((used));
1031-
void handle_hwdt_icache() {
1032-
Cache_Read_Enable(0, 0, ICACHE_SIZE_16);
1033-
handle_hwdt();
1034-
Cache_Read_Disable();
1035-
}
1036-
#endif // USE_IRAM
1037-
1038-
1039-
#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM)
1040-
static void printSanityCheck() {
1041-
ETS_PRINTF("\n\nsys_stack_first: %p\n", sys_stack_first);
1042-
ETS_PRINTF( "CONT_STACK: %p\n", CONT_STACK);
1043-
ETS_PRINTF( "g_pcont: %p\n", g_pcont);
1044-
ETS_PRINTF( "ROM_STACK: %p\n", ROM_STACK);
1045-
ETS_PRINTF( "get_noextra4k_g_pcont(): %p\n", get_noextra4k_g_pcont());
1046-
ETS_PRINTF( "g_rom_stack: %p\n", g_rom_stack);
1047-
ETS_PRINTF( "g_rom_stack_A16_sz: 0x%08X\n\n", g_rom_stack_A16_sz);
1048-
}
1049-
#endif //DEBUG_ESP_HWDT_DEV_DEBUG
10501040

10511041
/*
10521042
hwdt_pre_sdk_init() is the result of a hook for development diagnotics which
@@ -1071,9 +1061,8 @@ void hwdt_pre_sdk_init(void) {
10711061
#endif
10721062
}
10731063

1074-
static void IRAM_ATTR __attribute__((noinline)) hwdt_pre_sdk_init_icache(void) __attribute__((used));
1064+
static void __attribute__((noinline)) hwdt_pre_sdk_init_icache(void) __attribute__((used));
10751065
void hwdt_pre_sdk_init_icache(void) {
1076-
Cache_Read_Enable(0, 0, ICACHE_SIZE_16);
10771066
#ifdef DEBUG_ESP_HWDT_UART_SPEED
10781067
const uint32_t uart_divisor = set_uart_speed(0, DEBUG_ESP_HWDT_UART_SPEED);
10791068
#endif
@@ -1085,7 +1074,6 @@ void hwdt_pre_sdk_init_icache(void) {
10851074
adjust_uart_speed(uart_divisor);
10861075
}
10871076
#endif
1088-
Cache_Read_Disable();
10891077
}
10901078

10911079
/*
@@ -1106,6 +1094,7 @@ asm (
11061094
".literal .umm_init, umm_init\n\t"
11071095
".literal .call_user_start, call_user_start\n\t"
11081096
".literal .get_noextra4k_g_pcont, get_noextra4k_g_pcont\n\t"
1097+
".literal .mmu_wrap_irom_fn, mmu_wrap_irom_fn\n\t"
11091098
".align 4\n\t"
11101099
".global app_entry_redefinable\n\t"
11111100
".type app_entry_redefinable, @function\n\t"
@@ -1129,7 +1118,9 @@ asm (
11291118
#ifdef USE_IRAM
11301119
"call0 handle_hwdt\n\t"
11311120
#else
1132-
"call0 handle_hwdt_icache\n\t"
1121+
"l32r a0, .mmu_wrap_irom_fn\n\t"
1122+
"movi a2, handle_hwdt\n\t"
1123+
"callx0 a0\n\t"
11331124
#endif
11341125
/*
11351126
* Use new calculated SYS stack from top.
@@ -1160,7 +1151,9 @@ asm (
11601151
/*
11611152
* Allow for running additional diagnotics supplied at link time.
11621153
*/
1163-
"call0 hwdt_pre_sdk_init_icache\n\t"
1154+
"l32r a0, .mmu_wrap_irom_fn\n\t"
1155+
"movi a2, hwdt_pre_sdk_init_icache\n\t"
1156+
"callx0 a0\n\t"
11641157

11651158
// In case somebody cares, leave things as we found them
11661159
// - Restore ROM BSS zeros.
@@ -1174,7 +1167,12 @@ asm (
11741167
* improvements could possibly use hwdt_pre_sdk_init() to run other early
11751168
* diagnostic tools.
11761169
*/
1170+
#ifdef UMM_INIT_USE_IRAM
11771171
"l32r a0, .umm_init\n\t"
1172+
#else
1173+
"l32r a0, .mmu_wrap_irom_fn\n\t"
1174+
"l32r a2, .umm_init\n\t"
1175+
#endif
11781176
"callx0 a0\n\t"
11791177

11801178
"l32r a3, .call_user_start\n\t"

cores/esp8266/mmu_iram.cpp

+18-2
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919
#include "mmu_iram.h"
2020
#include <user_interface.h>
2121

22+
#define ICACHE_SIZE_32 1
23+
#define ICACHE_SIZE_16 0
24+
2225
extern "C" {
2326

2427
#if (MMU_ICACHE_SIZE == 0x4000)
25-
#define SOC_CACHE_SIZE 0 // 16KB
28+
#define SOC_CACHE_SIZE ICACHE_SIZE_16
2629
#pragma message("ICACHE size 16K")
2730
#else
28-
#define SOC_CACHE_SIZE 1 // 32KB
31+
#define SOC_CACHE_SIZE ICACHE_SIZE_32
2932
#endif
3033

3134
#if (MMU_ICACHE_SIZE == 0x4000)
@@ -185,8 +188,21 @@ extern "C" void pinMode( uint8_t pin, uint8_t mode ) {
185188

186189
__pinMode( pin, mode );
187190
}
191+
#else // #ifdef DEV_DEBUG_PRINT
192+
extern void Cache_Read_Disable(void);
188193
#endif // #ifdef DEV_DEBUG_PRINT
189194

195+
#else // #if (MMU_ICACHE_SIZE == 0x4000)
196+
extern void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v);
190197
#endif // #if (MMU_ICACHE_SIZE == 0x4000)
191198

199+
/*
200+
* This wrapper is for running code from IROM (flash) before the SDK starts.
201+
*/
202+
void IRAM_ATTR mmu_wrap_irom_fn(void (*fn)(void)) {
203+
Cache_Read_Enable(0, 0, ICACHE_SIZE_16);
204+
fn();
205+
Cache_Read_Disable();
206+
}
207+
192208
};

cores/esp8266/mmu_iram.h

+18
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ DBG_MMU_FLUSH(0)
8080
#define DBG_MMU_PRINTF(...) do {} while(false)
8181
#endif // defined(DEV_DEBUG_PRINT) || defined(DEBUG_ESP_MMU)
8282

83+
/*
84+
* This wrapper is for running code from IROM (flash) before the SDK starts.
85+
*
86+
* Wraps a `void fn(void)` call with calls to enable and disable iCACHE.
87+
* Allows a function that resides in IROM to run before the SDK starts.
88+
*
89+
* Do not use once the SDK has started.
90+
*
91+
* Because the SDK initialization code has not run, nearly all the SDK functions
92+
* are not safe to call.
93+
*
94+
* Note printing at this early stage is complicated. To gain more insight,
95+
* review DEV_DEBUG_PRINT build path in mmu_iram.cpp. To handle strings stored
96+
* in IROM, review printing method and comments in hwdt_app_entry.cpp.
97+
*
98+
*/
99+
void IRAM_ATTR mmu_wrap_irom_fn(void (*fn)(void));
100+
83101
static inline __attribute__((always_inline))
84102
bool mmu_is_iram(const void *addr) {
85103
const uintptr_t iram_start = (uintptr_t)XCHAL_INSTRAM1_VADDR;

cores/esp8266/umm_malloc/umm_info.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
void *umm_info(void *ptr, bool force) {
2929
UMM_CRITICAL_DECL(id_info);
3030

31-
UMM_INIT_HEAP;
31+
UMM_CHECK_INITIALIZED();
3232

3333
uint16_t blockNo = 0;
3434

cores/esp8266/umm_malloc/umm_integrity.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ bool umm_integrity_check(void) {
3333
uint16_t prev;
3434
uint16_t cur;
3535

36-
UMM_INIT_HEAP;
36+
UMM_CHECK_INITIALIZED();
3737

3838
/* Iterate through all free blocks */
3939
prev = 0;

cores/esp8266/umm_malloc/umm_local.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ size_t umm_block_size(void) {
166166
#if defined(UMM_STATS) || defined(UMM_STATS_FULL)
167167
// Keep complete call path in IRAM
168168
size_t umm_free_heap_size_lw(void) {
169-
UMM_INIT_HEAP;
169+
UMM_CHECK_INITIALIZED();
170170

171171
umm_heap_context_t *_context = umm_get_current_heap();
172172
return (size_t)_context->UMM_FREE_BLOCKS * sizeof(umm_block);

0 commit comments

Comments
 (0)