From 981c87899b565a9def5f12fc6ac337cf93078bf3 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Sun, 15 May 2016 10:36:33 +1000 Subject: [PATCH] Add heap information to fatal exception & abort dumps --- FreeRTOS/Source/portable/esp8266/port.c | 5 ++-- core/debug_dumps.c | 39 +++++++++++++++++++++++++ core/include/debug_dumps.h | 5 +++- core/include/xtensa_ops.h | 2 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/FreeRTOS/Source/portable/esp8266/port.c b/FreeRTOS/Source/portable/esp8266/port.c index 21a0d55..a9dac2d 100644 --- a/FreeRTOS/Source/portable/esp8266/port.c +++ b/FreeRTOS/Source/portable/esp8266/port.c @@ -73,6 +73,7 @@ #include #include #include +#include #include "FreeRTOS.h" #include "task.h" @@ -87,7 +88,7 @@ char level1_int_disabled; After tasks start, task stacks are all allocated from the heap and FreeRTOS checks for stack overflow. */ -static uint32_t xPortSupervisorStackPointer; +uint32_t xPortSupervisorStackPointer; /* * Stack initialization @@ -220,7 +221,7 @@ size_t xPortGetFreeHeapSize( void ) uint32_t sp = xPortSupervisorStackPointer; if(sp == 0) /* scheduler not started */ - __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp)); + SP(sp); return sp - brk_val + mi.fordblks; } diff --git a/core/debug_dumps.c b/core/debug_dumps.c index 15396ac..8b20c1b 100644 --- a/core/debug_dumps.c +++ b/core/debug_dumps.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "debug_dumps.h" #include "common_macros.h" @@ -156,18 +158,55 @@ static void fatal_exception_handler_inner(uint32_t *sp, bool registers_saved_on_ } dump_stack(sp); } + dump_heapinfo(); uart_flush_txfifo(0); uart_flush_txfifo(1); sdk_system_restart_in_nmi(); while(1) {} } +void dump_heapinfo(void) +{ + extern char _heap_start; + extern uint32_t xPortSupervisorStackPointer; + struct mallinfo mi = mallinfo(); + uint32_t brk_val = (uint32_t) sbrk(0); + uint32_t sp = xPortSupervisorStackPointer; + if(sp == 0) { + SP(sp); + } + + /* Total free heap is all memory that could be allocated via + malloc (assuming fragmentation doesn't become a problem) */ + printf("\nFree Heap: %d\n", sp - brk_val + mi.fordblks); + + /* delta between brk & supervisor sp is the contiguous memory + region that is available to be put into heap space via + brk(). */ + printf("_heap_start %p brk 0x%08x supervisor sp 0x%08x sp-brk %d bytes\n", + &_heap_start, brk_val, sp, sp-brk_val); + + /* arena/fordblks/uordblks determines the amount of free space + inside the heap region already added via brk(). May be + fragmented. + + The values in parentheses are the values used internally by + nano-mallocr.c, the field names outside parentheses are the + POSIX compliant field names of the mallinfo structure. + + "arena" should be equal to brk-_heap_start ie total size available. + */ + printf("arena (total_size) %d fordblks (free_size) %d uordblocks (used_size) %d\n", + mi.arena, mi.fordblks, mi.uordblks); +} + /* Main part of abort handler, can be run from flash to save some IRAM. */ static void abort_handler_inner(uint32_t *caller, uint32_t *sp) { printf("abort() invoked at %p.\n", caller); dump_stack(sp); + dump_heapinfo(); uart_flush_txfifo(0); uart_flush_txfifo(1); sdk_system_restart_in_nmi(); diff --git a/core/include/debug_dumps.h b/core/include/debug_dumps.h index 809b87a..ab3c972 100644 --- a/core/include/debug_dumps.h +++ b/core/include/debug_dumps.h @@ -10,9 +10,12 @@ #define _DEBUG_DUMPS_H #include -/* Dump stack memory starting from stack pointer address sp. */ +/* Dump stack memory to stdout, starting from stack pointer address sp. */ void dump_stack(uint32_t *sp); +/* Dump heap statistics to stdout */ +void dump_heapinfo(void); + /* Called from exception_vectors.S when a fatal exception occurs. Probably not useful to be called in other contexts. diff --git a/core/include/xtensa_ops.h b/core/include/xtensa_ops.h index 1ef68e9..52eba2a 100644 --- a/core/include/xtensa_ops.h +++ b/core/include/xtensa_ops.h @@ -19,7 +19,7 @@ * Note that the compiler will push a stack frame (minimum 16 bytes) * in the prelude of a C function that calls any other functions. */ -#define SP(var) asm volatile ("mov %0, a1" : "=r" (var)); +#define SP(var) asm volatile ("mov %0, a1" : "=r" (var)) /* Read the function return address to a variable. *