I did try that it gives 468940 this seems correct. I was allocating a huge array to use for memory.What does this do?It looks like the globals are at low addresses growing up. The heap is on top of that growing up. The stack is at high addresses growing down.Code:
&__HeapLimit - &__end__// Assumes you use up to 4K stacks per core(&__StackOneTop - (10 * 1024)) - &__end__// If you clobber
You have 2K stacks allocated for each core. You plan to clobber core1 or allocate on heap?
I've reversed the stacks positions so core one is at the end of memory and core zero can "safely" overflow. I tried but couldn't work out how to extend the stack size. This effort was a quite awhile ago now the result of was working out how to reverse the stacks.
It looks like an integer overflow, probably negative subtraction result seen as unsigned.Heap Size: 4294957056
Could you explain this formula ?P.S.printf("Heap size %u bytes\r\n", ((&__StackLimit - (10 * 1024)) - &__HeapLimit));
4294957056 = 0xFFFFD800 = -10240 = - (10 * 1024)
&__StackLimit = &__HeapLimit
I mentioned in my port that it was the -10k and something had gone wrong. The formula I don't remember how I came up with it, I was trying to replace pico_malloc with a custom allocator. &__HeapLimit was the address used for the start of heap. It's simpler to include the wrapper code
Code:
#include <stdlib.h>#include <stdio.h>#include "pico.h"#ifndef USE_MALLOC_MUTEX#define USE_MALLOC_MUTEX 1#include "pico/mutex.h"auto_init_mutex(malloc_mutex);#endif#include "umm_malloc.h"#include "umm_malloc_cfg.h" // Override with umm_malloc_cfg_xxx.hextern char __StackLimit; /* Set by linker. */extern char __HeapLimit;#ifndef STACK_EXTEND#define STACK_EXTEND 14#endif#define __HEAP_UPPER (&__StackLimit - (STACK_EXTEND * 1024))void *UMM_MALLOC_CFG_HEAP_ADDR = &__HeapLimit;uint32_t UMM_MALLOC_CFG_HEAP_SIZE = 0;static void stackoverflow_check() {#if 1 register char *sp asm("sp"); int r = sp - __HEAP_UPPER; if (r < 0) panic ("STACK OVERFLOW [%d bytes] sp = 0x%p, __StackLimit = 0x%p __HEAP_UPPER = 0x%p", r, sp, &__StackLimit, __HEAP_UPPER);#endif}static inline void check_alloc(__unused void *mem, __unused uint size) {#if UMM_POISON_CHECK if (umm_poison_check() == false) { panic("Heap poisoned"); }#endif#if UMM_INTEGRITY_CHECK if(umm_integrity_check() == 0) { panic("Heap integrity check failed"); }#endif if (!mem || (((char *)mem) + size) > __HEAP_UPPER) { panic("Out of memory"); } stackoverflow_check(); // if (((&__StackLimit - (char*)&mem) + size) > ((&__StackLimit - &__HeapLimit) - (1024 * 20))) puts("LOW WATER WATNING!"); // (0x20040000 - 0x2001649C); (0x20040000 - 0x200126f0); (186640 - 170852);}void *__wrap_malloc(size_t size) {#if USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK void *rc = umm_poison_malloc(size);#else void *rc = umm_malloc(size);#endif#if USE_MALLOC_MUTEX mutex_exit(&malloc_mutex);#endif#if PICO_DEBUG_MALLOC if (!rc || ((uint8_t *)rc) + size > (uint8_t*)PICO_DEBUG_MALLOC_LOW_WATER) { printf("malloc %d %p->%p\n", (uint) size, rc, ((uint8_t *) rc) + size); }#endif#if MEM_DEBUG_MALLOC printf("umm_malloc %d %p->%p\n", (uint) size, rc, ((uint8_t *) rc) + size);#endif check_alloc(rc, size); return rc;}void *__wrap_calloc(size_t count, size_t size) {#if USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK void *rc = umm_poison_calloc(count, size);#else void *rc = umm_calloc(count, size);#endif#if USE_MALLOC_MUTEX mutex_exit(&malloc_mutex);#endif#if PICO_DEBUG_MALLOC if (!rc || ((uint8_t *)rc) + size > (uint8_t*)PICO_DEBUG_MALLOC_LOW_WATER) { printf("calloc %d %p->%p\n", (uint) (count * size), rc, ((uint8_t *) rc) + size); }#endif#if MEM_DEBUG_MALLOC printf("umm_calloc %d %p->%p\n", (uint) (count * size), rc, ((uint8_t *) rc) + size);#endif check_alloc(rc, size); return rc;}void *__wrap_realloc(void *mem, size_t size) {#if USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK void *rc = umm_poison_realloc(mem, size);#else void *rc = umm_realloc(mem, size);#endif#if USE_MALLOC_MUTEX mutex_exit(&malloc_mutex);#endif#if PICO_DEBUG_MALLOC if (!rc || ((uint8_t *)rc) + size > (uint8_t*)PICO_DEBUG_MALLOC_LOW_WATER) { printf("realloc %p %d->%p\n", mem, (uint) size, rc); }#endif#if MEM_DEBUG_MALLOC printf("umm_realloc %p %d->%p\n", mem, (uint) size, rc);#endif check_alloc(rc, size); return rc;}void __wrap_free(void *mem) {#if USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK umm_poison_free(mem);#else umm_free(mem);#endif#if USE_MALLOC_MUTEX mutex_exit(&malloc_mutex);#endif}void init_memory(){ UMM_MALLOC_CFG_HEAP_SIZE = (__HEAP_UPPER - &__HeapLimit); umm_init();}
I haven't tried to compile for the RP2040 to see what is different, all I know right now is that with the allocator loaded the code doesn't work I'm not sure if we have an access violation or what. If I could keep core 1 running even where core 0 has panics then I might be able to see.
Statistics: Posted by DarkElvenAngel — Sat Dec 21, 2024 12:55 am