1
0
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:
M Hightower 2022-02-15 13:42:08 -08:00 committed by GitHub
parent d7c3d7b797
commit 7356cd1ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 290 additions and 166 deletions

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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"

View File

@ -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();
}
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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!

View 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

View File

@ -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();