mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
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.
This commit is contained in:
parent
d7c3d7b797
commit
7356cd1ef1
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -275,6 +275,7 @@
|
||||
#include <esp8266_peri.h>
|
||||
#include <uart.h>
|
||||
#include <pgmspace.h>
|
||||
#include "mmu_iram.h"
|
||||
|
||||
extern "C" {
|
||||
#include <user_interface.h>
|
||||
@ -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"
|
||||
|
@ -19,13 +19,16 @@
|
||||
#include "mmu_iram.h"
|
||||
#include <user_interface.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <pgmspace.h>
|
||||
#include <mmu_iram.h>
|
||||
#include "../debug.h"
|
||||
#include "../esp8266_undocumented.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <core_esp8266_features.h>
|
||||
#include <stdlib.h>
|
||||
#include <osapi.h>
|
||||
|
||||
#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!
|
||||
|
91
cores/esp8266/umm_malloc/umm_malloc_cfgport.h
Normal file
91
cores/esp8266/umm_malloc/umm_malloc_cfgport.h
Normal file
@ -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 <pgmspace.h>
|
||||
#include <mmu_iram.h>
|
||||
#include "../debug.h"
|
||||
#include "../esp8266_undocumented.h"
|
||||
|
||||
#include <core_esp8266_features.h>
|
||||
#include <stdlib.h>
|
||||
#include <osapi.h>
|
||||
|
||||
#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
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user