diff --git a/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp b/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp index 58f615c784..0c0eac4d48 100644 --- a/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp +++ b/cores/esp8266/core_esp8266_app_entry_noextra4k.cpp @@ -39,7 +39,19 @@ extern "C" void app_entry_redefinable(void) { g_pcont = &g_cont; + #ifdef UMM_INIT_USE_IRAM + /* + * Legacy option: the umm_init() call path must reside in IRAM. + */ umm_init(); + #else + /* + * Instruction cache is enabled/disabled around running umm_init(). + * Allows the use of IROM (flash) to store umm_init(). + */ + mmu_wrap_irom_fn(umm_init); + #endif + /* Call the entry point of the SDK code. */ call_user_start(); } diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 39decfb12f..430808f19d 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -365,7 +365,12 @@ extern "C" void app_entry_redefinable(void) /* Doing umm_init just once before starting the SDK, allowed us to remove test and init calls at each malloc API entry point, saving IRAM. */ +#ifdef UMM_INIT_USE_IRAM umm_init(); +#else + // umm_init() is in IROM + mmu_wrap_irom_fn(umm_init); +#endif /* Call the entry point of the SDK code. */ call_user_start(); } diff --git a/cores/esp8266/hwdt_app_entry.cpp b/cores/esp8266/hwdt_app_entry.cpp index 22a91a6bee..8177832b9e 100644 --- a/cores/esp8266/hwdt_app_entry.cpp +++ b/cores/esp8266/hwdt_app_entry.cpp @@ -275,6 +275,7 @@ #include #include #include +#include "mmu_iram.h" extern "C" { #include @@ -1007,6 +1008,18 @@ STATIC void IRAM_MAYBE handle_hwdt(void) { #endif } +#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM) +static void printSanityCheck() { + ETS_PRINTF("\n\nsys_stack_first: %p\n", sys_stack_first); + ETS_PRINTF( "CONT_STACK: %p\n", CONT_STACK); + ETS_PRINTF( "g_pcont: %p\n", g_pcont); + ETS_PRINTF( "ROM_STACK: %p\n", ROM_STACK); + ETS_PRINTF( "get_noextra4k_g_pcont(): %p\n", get_noextra4k_g_pcont()); + ETS_PRINTF( "g_rom_stack: %p\n", g_rom_stack); + ETS_PRINTF( "g_rom_stack_A16_sz: 0x%08X\n\n", g_rom_stack_A16_sz); +} +#endif //DEBUG_ESP_HWDT_DEV_DEBUG + /* * Using Cache_Read_Enable/Cache_Read_Disable to reduce IRAM usage. Moved * 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) { * https://richard.burtons.org/2015/06/12/esp8266-cache_read_enable/. * Additional insight can be gleemed from reviewing the ESP8266_RTOS_SDK. * (eg. ../components/bootloader_support/src/bootloader_utility.c) + * + * The logic to use Cache_Read_Enable and Cache_Read_Disable has been + * generalized into a wrapper function, mmu_wrap_irom_fn, and moved to + * mmu_iram.cpp. */ -#define ICACHE_SIZE_32 1 -#define ICACHE_SIZE_16 0 - -extern "C" void Cache_Read_Disable(void); -extern "C" void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v); - -#ifndef USE_IRAM -static void IRAM_ATTR __attribute__((noinline)) handle_hwdt_icache() __attribute__((used)); -void handle_hwdt_icache() { - Cache_Read_Enable(0, 0, ICACHE_SIZE_16); - handle_hwdt(); - Cache_Read_Disable(); -} -#endif // USE_IRAM - - -#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM) -static void printSanityCheck() { - ETS_PRINTF("\n\nsys_stack_first: %p\n", sys_stack_first); - ETS_PRINTF( "CONT_STACK: %p\n", CONT_STACK); - ETS_PRINTF( "g_pcont: %p\n", g_pcont); - ETS_PRINTF( "ROM_STACK: %p\n", ROM_STACK); - ETS_PRINTF( "get_noextra4k_g_pcont(): %p\n", get_noextra4k_g_pcont()); - ETS_PRINTF( "g_rom_stack: %p\n", g_rom_stack); - ETS_PRINTF( "g_rom_stack_A16_sz: 0x%08X\n\n", g_rom_stack_A16_sz); -} -#endif //DEBUG_ESP_HWDT_DEV_DEBUG /* hwdt_pre_sdk_init() is the result of a hook for development diagnotics which @@ -1071,9 +1061,8 @@ void hwdt_pre_sdk_init(void) { #endif } -static void IRAM_ATTR __attribute__((noinline)) hwdt_pre_sdk_init_icache(void) __attribute__((used)); +static void __attribute__((noinline)) hwdt_pre_sdk_init_icache(void) __attribute__((used)); void hwdt_pre_sdk_init_icache(void) { - Cache_Read_Enable(0, 0, ICACHE_SIZE_16); #ifdef DEBUG_ESP_HWDT_UART_SPEED const uint32_t uart_divisor = set_uart_speed(0, DEBUG_ESP_HWDT_UART_SPEED); #endif @@ -1085,7 +1074,6 @@ void hwdt_pre_sdk_init_icache(void) { adjust_uart_speed(uart_divisor); } #endif - Cache_Read_Disable(); } /* @@ -1106,6 +1094,7 @@ asm ( ".literal .umm_init, umm_init\n\t" ".literal .call_user_start, call_user_start\n\t" ".literal .get_noextra4k_g_pcont, get_noextra4k_g_pcont\n\t" + ".literal .mmu_wrap_irom_fn, mmu_wrap_irom_fn\n\t" ".align 4\n\t" ".global app_entry_redefinable\n\t" ".type app_entry_redefinable, @function\n\t" @@ -1129,7 +1118,9 @@ asm ( #ifdef USE_IRAM "call0 handle_hwdt\n\t" #else - "call0 handle_hwdt_icache\n\t" + "l32r a0, .mmu_wrap_irom_fn\n\t" + "movi a2, handle_hwdt\n\t" + "callx0 a0\n\t" #endif /* * Use new calculated SYS stack from top. @@ -1160,7 +1151,9 @@ asm ( /* * Allow for running additional diagnotics supplied at link time. */ - "call0 hwdt_pre_sdk_init_icache\n\t" + "l32r a0, .mmu_wrap_irom_fn\n\t" + "movi a2, hwdt_pre_sdk_init_icache\n\t" + "callx0 a0\n\t" // In case somebody cares, leave things as we found them // - Restore ROM BSS zeros. @@ -1174,7 +1167,12 @@ asm ( * improvements could possibly use hwdt_pre_sdk_init() to run other early * diagnostic tools. */ +#ifdef UMM_INIT_USE_IRAM "l32r a0, .umm_init\n\t" +#else + "l32r a0, .mmu_wrap_irom_fn\n\t" + "l32r a2, .umm_init\n\t" +#endif "callx0 a0\n\t" "l32r a3, .call_user_start\n\t" diff --git a/cores/esp8266/mmu_iram.cpp b/cores/esp8266/mmu_iram.cpp index 7a3548e4a3..9f1b05d455 100644 --- a/cores/esp8266/mmu_iram.cpp +++ b/cores/esp8266/mmu_iram.cpp @@ -19,13 +19,16 @@ #include "mmu_iram.h" #include +#define ICACHE_SIZE_32 1 +#define ICACHE_SIZE_16 0 + extern "C" { #if (MMU_ICACHE_SIZE == 0x4000) -#define SOC_CACHE_SIZE 0 // 16KB +#define SOC_CACHE_SIZE ICACHE_SIZE_16 #pragma message("ICACHE size 16K") #else -#define SOC_CACHE_SIZE 1 // 32KB +#define SOC_CACHE_SIZE ICACHE_SIZE_32 #endif #if (MMU_ICACHE_SIZE == 0x4000) @@ -185,8 +188,21 @@ extern "C" void pinMode( uint8_t pin, uint8_t mode ) { __pinMode( pin, mode ); } +#else // #ifdef DEV_DEBUG_PRINT +extern void Cache_Read_Disable(void); #endif // #ifdef DEV_DEBUG_PRINT +#else // #if (MMU_ICACHE_SIZE == 0x4000) +extern void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v); #endif // #if (MMU_ICACHE_SIZE == 0x4000) +/* + * This wrapper is for running code from IROM (flash) before the SDK starts. + */ +void IRAM_ATTR mmu_wrap_irom_fn(void (*fn)(void)) { + Cache_Read_Enable(0, 0, ICACHE_SIZE_16); + fn(); + Cache_Read_Disable(); +} + }; diff --git a/cores/esp8266/mmu_iram.h b/cores/esp8266/mmu_iram.h index f7b62ba8c2..121226bd4c 100644 --- a/cores/esp8266/mmu_iram.h +++ b/cores/esp8266/mmu_iram.h @@ -80,6 +80,24 @@ DBG_MMU_FLUSH(0) #define DBG_MMU_PRINTF(...) do {} while(false) #endif // defined(DEV_DEBUG_PRINT) || defined(DEBUG_ESP_MMU) +/* + * This wrapper is for running code from IROM (flash) before the SDK starts. + * + * Wraps a `void fn(void)` call with calls to enable and disable iCACHE. + * Allows a function that resides in IROM to run before the SDK starts. + * + * Do not use once the SDK has started. + * + * Because the SDK initialization code has not run, nearly all the SDK functions + * are not safe to call. + * + * Note printing at this early stage is complicated. To gain more insight, + * review DEV_DEBUG_PRINT build path in mmu_iram.cpp. To handle strings stored + * in IROM, review printing method and comments in hwdt_app_entry.cpp. + * + */ +void IRAM_ATTR mmu_wrap_irom_fn(void (*fn)(void)); + static inline __attribute__((always_inline)) bool mmu_is_iram(const void *addr) { const uintptr_t iram_start = (uintptr_t)XCHAL_INSTRAM1_VADDR; diff --git a/cores/esp8266/umm_malloc/umm_info.c b/cores/esp8266/umm_malloc/umm_info.c index bd3280baed..4a95e994c3 100644 --- a/cores/esp8266/umm_malloc/umm_info.c +++ b/cores/esp8266/umm_malloc/umm_info.c @@ -28,7 +28,7 @@ void *umm_info(void *ptr, bool force) { UMM_CRITICAL_DECL(id_info); - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); uint16_t blockNo = 0; diff --git a/cores/esp8266/umm_malloc/umm_integrity.c b/cores/esp8266/umm_malloc/umm_integrity.c index c66ec3bb00..c652562f99 100644 --- a/cores/esp8266/umm_malloc/umm_integrity.c +++ b/cores/esp8266/umm_malloc/umm_integrity.c @@ -33,7 +33,7 @@ bool umm_integrity_check(void) { uint16_t prev; uint16_t cur; - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); /* Iterate through all free blocks */ prev = 0; diff --git a/cores/esp8266/umm_malloc/umm_local.c b/cores/esp8266/umm_malloc/umm_local.c index 24ddf8ce06..035d8a0d55 100644 --- a/cores/esp8266/umm_malloc/umm_local.c +++ b/cores/esp8266/umm_malloc/umm_local.c @@ -166,7 +166,7 @@ size_t umm_block_size(void) { #if defined(UMM_STATS) || defined(UMM_STATS_FULL) // Keep complete call path in IRAM size_t umm_free_heap_size_lw(void) { - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); umm_heap_context_t *_context = umm_get_current_heap(); return (size_t)_context->UMM_FREE_BLOCKS * sizeof(umm_block); diff --git a/cores/esp8266/umm_malloc/umm_malloc.cpp b/cores/esp8266/umm_malloc/umm_malloc.cpp index d3f4c92c66..78d20c98d0 100644 --- a/cores/esp8266/umm_malloc/umm_malloc.cpp +++ b/cores/esp8266/umm_malloc/umm_malloc.cpp @@ -63,24 +63,26 @@ extern "C" { #define DBGLOG_LEVEL 0 #endif -// Save 104 bytes by calling umm_init() early once from app_entry() -// Some minor UMM_CRITICAL_METRICS counts will be lost through CRT0 init. -// #define UMM_INIT_HEAP if (!umm_heap) { umm_init(); } -#define UMM_INIT_HEAP (void)0 - #include "dbglog/dbglog.h" -// C This change is new in upstream umm_malloc.I think this would have created a -// C breaking change. Keeping the old #define method in umm_malloc_cfg.h. -// C I don't see a simple way of making it work. We would have to run code before -// C the SDK has run to set a value for uint32_t UMM_MALLOC_CFG_HEAP_SIZE. -// C On the other hand, a manual call to umm_init() before anything else has had a -// C chance to run would mean that all those calls testing to see if the heap has -// C been initialized at every umm_malloc API could be removed. -// C -// C before starting the NON OS SDK -// C extern void *UMM_MALLOC_CFG_HEAP_ADDR; -// C extern uint32_t UMM_MALLOC_CFG_HEAP_SIZE; +/* + * These variables are used in upstream umm_malloc for initializing the heap. + * Our port initialization is different and does not use them at this time. +extern void *UMM_MALLOC_CFG_HEAP_ADDR; +extern uint32_t UMM_MALLOC_CFG_HEAP_SIZE; + */ +/* + * In our port, we leave UMM_CHECK_INITIALIZED unset. Since we initialize the + * heap before CRT0 init has run, commonly used testing methods for heap init + * may not work. Not using UMM_CHECK_INITIALIZED saves about 104 bytes of IRAM. + * + * In our configuration app_entry_redefinable() must call umm_init(), before + * calling the SDK's app_entry_custom(). The DRAM Heap must be available before + * the SDK starts. + * + * If building with UMM_CRITICAL_METRICS, some minor counts will be lost through + * CRT0 init. + */ #include "umm_local.h" // target-dependent supplemental @@ -91,7 +93,6 @@ UMM_H_ATTPACKPRE typedef struct umm_ptr_t { uint16_t prev; } UMM_H_ATTPACKSUF umm_ptr; - UMM_H_ATTPACKPRE typedef struct umm_block_t { union { umm_ptr used; @@ -425,21 +426,30 @@ static uint16_t umm_assimilate_down(umm_heap_context_t *_context, uint16_t c, ui } /* ------------------------------------------------------------------------- */ - -static void umm_init_stage_2(umm_heap_context_t *_context) { +#undef ICACHE_MAYBE +#ifdef UMM_INIT_USE_IRAM +// umm_init(), ... stays in IRAM +#define ICACHE_MAYBE +#else +// Freeup IRAM +#define ICACHE_MAYBE ICACHE_FLASH_ATTR +#endif +/* + * In this port, we split the upstream version of umm_init_heap() into two + * parts: _umm_init_heap and umm_init_heap. Then add multiple heap support. + */ +static void ICACHE_MAYBE _umm_init_heap(umm_heap_context_t *_context) { /* setup initial blank heap structure */ UMM_FRAGMENTATION_METRIC_INIT(); /* init stats.free_blocks */ - #if defined(UMM_STATS) || defined(UMM_STATS_FULL) #if defined(UMM_STATS_FULL) - _context->stats.free_blocks_min = - _context->stats.free_blocks_isr_min = UMM_NUMBLOCKS - 2; + _context->stats.free_blocks_min = UMM_NUMBLOCKS - 2; + _context->stats.free_blocks_isr_min = UMM_NUMBLOCKS - 2; #endif - #ifndef UMM_INLINE_METRICS + #if (defined(UMM_STATS) || defined(UMM_STATS_FULL)) && !defined(UMM_INLINE_METRICS) _context->stats.free_blocks = UMM_NUMBLOCKS - 2; #endif - #endif /* Set up umm_block[0], which just points to umm_block[1] */ UMM_NBLOCK(0) = 1; @@ -478,78 +488,91 @@ static void umm_init_stage_2(umm_heap_context_t *_context) { UMM_PBLOCK(UMM_BLOCK_LAST) = 1; } - -void umm_init_common(size_t id, void *start_addr, size_t size, bool zero) { - /* Preserve internal setup */ +void ICACHE_MAYBE umm_init_heap(size_t id, void *start_addr, size_t size, bool full_init) { + /* Check for bad values and block duplicate init attempts. */ umm_heap_context_t *_context = umm_get_heap_by_id(id); if (NULL == start_addr || NULL == _context || _context->heap) { return; } /* init heap pointer and size, and memset it to 0 */ + _context->id = id; _context->heap = (umm_block *)start_addr; _context->heap_end = (void *)((uintptr_t)start_addr + size); _context->numblocks = (size / sizeof(umm_block)); - // An option for blocking the zeroing of extra heaps allows for performing - // post-crash discovery. - if (zero) { + // An option for blocking the zeroing of extra heaps. This allows for + // post-crash debugging after reboot. + if (full_init) { memset(_context->heap, 0x00, size); #if (!defined(UMM_INLINE_METRICS) && defined(UMM_STATS)) || defined(UMM_STATS_FULL) memset(&_context->stats, 0x00, sizeof(_context->stats)); #endif /* Set up internal data structures */ - umm_init_stage_2(_context); + _umm_init_heap(_context); } } -void umm_init(void) { - // if (umm_heap) { - // return; - // } +void ICACHE_MAYBE umm_init(void) { + + // We can get called before "C" runtime has run. Here we handles that + // beginning of time initialization. As such heap_context[] must be + // defined with attributes to prevent initialization by the "C" runtime. + // A late "C" runtime init would destroy our work. + + // Assume no "C" runtime zero init for (size_t i = 0; i < UMM_NUM_HEAPS; i++) { heap_context[i].heap = NULL; } memset(&heap_context[0], 0, sizeof(heap_context)); - umm_init_common(UMM_HEAP_DRAM, (void *)UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE, true); - // umm_heap = (void *)&heap_context; + // Note, full_init must be true for the primary heap, DRAM. + umm_init_heap(UMM_HEAP_DRAM, (void *)UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE, true); + + // upstream ref: + // Initialize the heap from linker supplied values */ + // umm_init_heap(UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE); } +/* + * Only the Internal DRAM init, needs (or maybe not) to be called from IRAM. + * umm_init_iram and umm_init_vm are called from user_init() after the SDK has + * inited and ICACHE has been enabled. + */ #ifdef UMM_HEAP_IRAM -void umm_init_iram_ex(void *addr, unsigned int size, bool zero) { +void ICACHE_FLASH_ATTR umm_init_iram_ex(void *addr, unsigned int size, bool full_init) { /* We need the main, internal heap set up first */ - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); - umm_init_common(UMM_HEAP_IRAM, addr, size, zero); + umm_init_heap(UMM_HEAP_IRAM, addr, size, full_init); } void _text_end(void); -void umm_init_iram(void) __attribute__((weak)); +void ICACHE_FLASH_ATTR umm_init_iram(void) __attribute__((weak)); /* By using a weak link, it is possible to reduce the IRAM heap size with a user-supplied init function. This would allow the creation of a block of IRAM dedicated to a sketch and possibly used/preserved across reboots. */ -void umm_init_iram(void) { +void ICACHE_FLASH_ATTR umm_init_iram(void) { umm_init_iram_ex(mmu_sec_heap(), mmu_sec_heap_size(), true); } #endif // #ifdef UMM_HEAP_IRAM #ifdef UMM_HEAP_EXTERNAL -void umm_init_vm(void *vmaddr, unsigned int vmsize) { +void ICACHE_FLASH_ATTR umm_init_vm(void *vmaddr, unsigned int vmsize) { /* We need the main, internal (DRAM) heap set up first */ - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); - umm_init_common(UMM_HEAP_EXTERNAL, vmaddr, vmsize, true); + umm_init_heap(UMM_HEAP_EXTERNAL, vmaddr, vmsize, true); } #endif /* ------------------------------------------------------------------------ * Must be called only from within critical sections guarded by - * UMM_CRITICAL_ENTRY() and UMM_CRITICAL_EXIT(). + * UMM_CRITICAL_ENTRY(id) and UMM_CRITICAL_EXIT(id). */ static void umm_free_core(umm_heap_context_t *_context, void *ptr) { @@ -614,7 +637,7 @@ static void umm_free_core(umm_heap_context_t *_context, void *ptr) { void umm_free(void *ptr) { UMM_CRITICAL_DECL(id_free); - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); /* If we're being asked to free a NULL pointer, well that's just silly! */ @@ -769,7 +792,7 @@ void *umm_malloc(size_t size) { void *ptr = NULL; - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); /* * "Is it safe" @@ -878,7 +901,7 @@ void *umm_realloc(void *ptr, size_t size) { size_t curSize; - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); /* * This code looks after the case of a NULL value for ptr. The ANSI C diff --git a/cores/esp8266/umm_malloc/umm_malloc_cfg.h b/cores/esp8266/umm_malloc/umm_malloc_cfg.h index 3ec44c1f40..b7a090f7f2 100644 --- a/cores/esp8266/umm_malloc/umm_malloc_cfg.h +++ b/cores/esp8266/umm_malloc/umm_malloc_cfg.h @@ -1,14 +1,16 @@ /* - * Configuration for umm_malloc - target Arduino ESP8266 core - * - * Changes specific to a target platform go here. - * - * This comment section changed to below in the upstream version, keeping old method for now. - * * Configuration for umm_malloc - DO NOT EDIT THIS FILE BY HAND! * - * Refer to the notes below for how to configure the build at compile time - * using -D to define non-default values + * NOTE WELL: Your project MUST have a umm_malloc_cfgport.h - even if + * it's empty!!! + * + * Refer to the notes below for details on the umm_malloc configuration + * options. + */ + +/* + * Minimized changes in umm_malloc_cfg.h, transition Arduino ESP8266 specific + * changes to umm_malloc_cfgport.h. */ #ifndef _UMM_MALLOC_CFG_H @@ -18,65 +20,10 @@ #include #include -#include -#include -#include "../debug.h" -#include "../esp8266_undocumented.h" - #ifdef __cplusplus extern "C" { #endif -#include -#include -#include - -#include "c_types.h" - -/* - * Define active Heaps - */ -#if defined(MMU_IRAM_HEAP) -#define UMM_HEAP_IRAM -#else -#undef UMM_HEAP_IRAM -#endif - -#if defined(MMU_EXTERNAL_HEAP) -#define UMM_HEAP_EXTERNAL -#else -#undef UMM_HEAP_EXTERNAL -#endif - -/* - * Assign IDs to active Heaps and tally. DRAM is always active. - */ -#define UMM_HEAP_DRAM 0 -#define UMM_HEAP_DRAM_DEFINED 1 - -#ifdef UMM_HEAP_IRAM -#undef UMM_HEAP_IRAM -#define UMM_HEAP_IRAM_DEFINED 1 -#define UMM_HEAP_IRAM UMM_HEAP_DRAM_DEFINED -#else -#define UMM_HEAP_IRAM_DEFINED 0 -#endif - -#ifdef UMM_HEAP_EXTERNAL -#undef UMM_HEAP_EXTERNAL -#define UMM_HEAP_EXTERNAL_DEFINED 1 -#define UMM_HEAP_EXTERNAL (UMM_HEAP_DRAM_DEFINED + UMM_HEAP_IRAM_DEFINED) -#else -#define UMM_HEAP_EXTERNAL_DEFINED 0 -#endif - -#define UMM_NUM_HEAPS (UMM_HEAP_DRAM_DEFINED + UMM_HEAP_IRAM_DEFINED + UMM_HEAP_EXTERNAL_DEFINED) - -#if (UMM_NUM_HEAPS == 1) -#else -#define UMM_HEAP_STACK_DEPTH 32 -#endif - /* * There are a number of defines you can set at compile time that affect how * the memory allocator will operate. @@ -116,6 +63,16 @@ extern "C" { * Setting this at compile time will automatically set UMM_INFO. * Note that enabling this define will add a slight runtime penalty. * + * UMM_CHECK_INITIALIZED + * + * Set if you want to be able to verify that the heap is intialized + * before any operation - the default is no check. You may set the + * UMM_CHECK_INITIALIZED macro to the following provided macros, or + * write your own handler: + * + * UMM_INIT_IF_UNINITIALIZED + * UMM_HANG_IF_UNINITIALIZED + * * UMM_INTEGRITY_CHECK * * Set if you want to be able to verify that the heap is semantically correct @@ -143,6 +100,12 @@ extern "C" { * ---------------------------------------------------------------------------- */ +#ifdef UMM_CFGFILE +#include UMM_CFGFILE +#else +#include "umm_malloc_cfgport.h" +#endif + #define UMM_BEST_FIT #define UMM_INFO // #define UMM_INLINE_METRICS @@ -168,22 +131,6 @@ extern "C" { */ -#ifdef UMM_TEST_BUILD -extern char test_umm_heap[]; -#endif - -#ifdef UMM_TEST_BUILD -/* Start addresses and the size of the heap */ -#define UMM_MALLOC_CFG_HEAP_ADDR (test_umm_heap) -#define UMM_MALLOC_CFG_HEAP_SIZE 0x10000 -#else -/* Start addresses and the size of the heap */ -extern char _heap_start[]; -#define UMM_HEAP_END_ADDR 0x3FFFC000UL -#define UMM_MALLOC_CFG_HEAP_ADDR ((uint32_t)&_heap_start[0]) -#define UMM_MALLOC_CFG_HEAP_SIZE ((size_t)(UMM_HEAP_END_ADDR - UMM_MALLOC_CFG_HEAP_ADDR)) -#endif - /* A couple of macros to make packing structures less compiler dependent */ #define UMM_H_ATTPACKPRE @@ -191,6 +138,20 @@ extern char _heap_start[]; /* -------------------------------------------------------------------------- */ +#ifndef UMM_INIT_IF_UNINITIALIZED + #define UMM_INIT_IF_UNINITIALIZED() do { if (UMM_HEAP == NULL) { umm_init(); } } while (0) +#endif + +#ifndef UMM_HANG_IF_UNINITIALIZED + #define UMM_HANG_IF_UNINITIALIZED() do { if (UMM_HEAP == NULL) { while (1) {} } } while (0) +#endif + +#ifndef UMM_CHECK_INITIALIZED + #define UMM_CHECK_INITIALIZED() +#endif + +/* -------------------------------------------------------------------------- */ + #ifdef UMM_BEST_FIT #ifdef UMM_FIRST_FIT #error Both UMM_BEST_FIT and UMM_FIRST_FIT are defined - pick one! diff --git a/cores/esp8266/umm_malloc/umm_malloc_cfgport.h b/cores/esp8266/umm_malloc/umm_malloc_cfgport.h new file mode 100644 index 0000000000..02db6fc66c --- /dev/null +++ b/cores/esp8266/umm_malloc/umm_malloc_cfgport.h @@ -0,0 +1,91 @@ +#ifndef _UMM_MALLOC_CFGPORT_H +#define _UMM_MALLOC_CFGPORT_H + +#ifndef _UMM_MALLOC_CFG_H +#error "This include file must be used with umm_malloc_cfg.h" +#endif + +/* + * Arduino ESP8266 core umm_malloc port config + */ +#include +#include +#include "../debug.h" +#include "../esp8266_undocumented.h" + +#include +#include +#include + +#include "c_types.h" + +/* + * -DUMM_INIT_USE_IRAM + * + * Historically, the umm_init() call path has been in IRAM. The umm_init() call + * path is now in ICACHE (flash). Use the build option UMM_INIT_USE_IRAM to + * restore the legacy behavor. + * + * If you have your own app_entry_redefinable() function, see + * app_entry_redefinable() in core_esp8266_app_entry_noextra4k.cpp for an + * example of how to toggle between ICACHE and IRAM in your build. + * + * The default is to use ICACHE. + */ +// #define UMM_INIT_USE_IRAM 1 + + +/* + * Start addresses and the size of the heap + */ +extern char _heap_start[]; +#define UMM_HEAP_END_ADDR 0x3FFFC000UL +#define UMM_MALLOC_CFG_HEAP_ADDR ((uint32_t)&_heap_start[0]) +#define UMM_MALLOC_CFG_HEAP_SIZE ((size_t)(UMM_HEAP_END_ADDR - UMM_MALLOC_CFG_HEAP_ADDR)) + +/* + * Define active Heaps + */ +#if defined(MMU_IRAM_HEAP) +#define UMM_HEAP_IRAM +#else +#undef UMM_HEAP_IRAM +#endif + +#if defined(MMU_EXTERNAL_HEAP) +#define UMM_HEAP_EXTERNAL +#else +#undef UMM_HEAP_EXTERNAL +#endif + +/* + * Assign IDs to active Heaps and tally. DRAM is always active. + */ +#define UMM_HEAP_DRAM 0 +#define UMM_HEAP_DRAM_DEFINED 1 + +#ifdef UMM_HEAP_IRAM +#undef UMM_HEAP_IRAM +#define UMM_HEAP_IRAM_DEFINED 1 +#define UMM_HEAP_IRAM UMM_HEAP_DRAM_DEFINED +#else +#define UMM_HEAP_IRAM_DEFINED 0 +#endif + +#ifdef UMM_HEAP_EXTERNAL +#undef UMM_HEAP_EXTERNAL +#define UMM_HEAP_EXTERNAL_DEFINED 1 +#define UMM_HEAP_EXTERNAL (UMM_HEAP_DRAM_DEFINED + UMM_HEAP_IRAM_DEFINED) +#else +#define UMM_HEAP_EXTERNAL_DEFINED 0 +#endif + +#define UMM_NUM_HEAPS (UMM_HEAP_DRAM_DEFINED + UMM_HEAP_IRAM_DEFINED + UMM_HEAP_EXTERNAL_DEFINED) + +#if (UMM_NUM_HEAPS == 1) +#else +#define UMM_HEAP_STACK_DEPTH 32 +#endif + + +#endif diff --git a/cores/esp8266/umm_malloc/umm_poison.c b/cores/esp8266/umm_malloc/umm_poison.c index a7a3fa2179..802e580617 100644 --- a/cores/esp8266/umm_malloc/umm_poison.c +++ b/cores/esp8266/umm_malloc/umm_poison.c @@ -227,7 +227,7 @@ bool umm_poison_check(void) { bool ok = true; uint16_t cur; - UMM_INIT_HEAP; + UMM_CHECK_INITIALIZED(); UMM_CRITICAL_ENTRY(id_poison); umm_heap_context_t *_context = umm_get_current_heap(); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy