Add heap information to fatal exception & abort dumps
This commit is contained in:
		
							parent
							
								
									efedd24624
								
							
						
					
					
						commit
						981c87899b
					
				
					 4 changed files with 47 additions and 4 deletions
				
			
		|  | @ -73,6 +73,7 @@ | |||
| #include <malloc.h> | ||||
| #include <unistd.h> | ||||
| #include <stdio.h> | ||||
| #include <xtensa_ops.h> | ||||
| 
 | ||||
| #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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,8 @@ | |||
| #include <stdio.h> | ||||
| #include <FreeRTOS.h> | ||||
| #include <task.h> | ||||
| #include <malloc.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #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(); | ||||
|  |  | |||
|  | @ -10,9 +10,12 @@ | |||
| #define _DEBUG_DUMPS_H | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| /* 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. | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  * | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue