heap_5 allocating outside of allowed range

I’m using STM32F4 which has 192+64 KB of RAM. To use the 64KB I’m using heap_5. Currently the heap is initialized for the 64KB plus the upper 64KB of the 192KB. From the linker script file: ~~~~~ define symbol regionHEAP1_start = 0x10000000; define symbol regionHEAP1_end = 0x1000FFFF; define symbol regionHEAP2_start = 0x20010000; define symbol regionHEAP2_end = 0x2002FFFF; ~~~~~ Heap initialization code: ~~~~~ HeapRegiont xHeapRegions[] = { { ( uint8t * ) 0, 0}, { ( uint8_t * ) 0, 0}, { NULL, 0}//<< Terminates the array. }; void fillHeapRegions() { xHeapRegions[0].pucStartAddress = &regionHEAP1_start; xHeapRegions[0].xSizeInBytes = &regionHEAP1_end-&regionHEAP1_start; xHeapRegions[1].pucStartAddress = &regionHEAP2_start; xHeapRegions[1].xSizeInBytes = &regionHEAP2_end-&regionHEAP2_start; } ~~~~~~ I’m calling fillHeapRegions before calling vPortDefineHeapRegions(xHeapRegions) in main. My application works fine with this configuration. The problem I’m witnessing is if I reduce the size of the memory region allocated to the heap: ~~~~~~ define symbol regionHEAP1_start = 0x10000000; define symbol regionHEAP1_end = 0x1000FFFF; define symbol regionHEAP2_start = 0x20012000; define symbol regionHEAP2_end = 0x2002FFFF; ~~~~~~ I’m getting sporadic application crashes. When I investigated those crashes I saw a pointer to 0x20030000. Naturally this would cause a hard fault as this address is outside allowed address space. Any idea? Thanks, Maor

heap_5 allocating outside of allowed range

Hi Maor,
I’m getting sporadic application crashes
I would wonder if all memories given to the HEAP is not used by your program or by some stack? You can also set the sizes more dynamically. If your linker file contains symbols like:
_ebss = . ;
_edata = . ;
you can obtain the addresses of these variable in your C code:
extern void _edata;
extern void _ebss;
and convert them to real addresses:
uint32_t end_data = ( uint32_t ) &_edata;
uint32_t end_bss = ( uint32_t ) &_ebss;
A small remark about your code:
xSizeInBytes = &__region_HEAP_1_end__ - &__region_HEAP_1_start__;
Shouldn’t it be: size = end - start + 1 ? Regards.

heap_5 allocating outside of allowed range

First, the memory is divided to three segments, one for the statically allocated memories and the other two for the segmented heap. As an architectural limit, I can’t move the static memories to the lower segment as hardware peripherals don’t work there. I started the allocation by giving 64K to the static memories, and 64+64K to the heap. I got a linking error when I needed more statically allocated memory and I resized the segments accordingly. At this point I started getting the crashes. As for the size in bytes, it really doesn’t matter – I shouldn’t be getting allocation addresses outside of the allowed range.

heap_5 allocating outside of allowed range

define symbol regionHEAP1_start = 0x10000000; xHeapRegions[0].pucStartAddress = &regionHEAP1_start;
What compiler is that? Can you check it is doing what you think by looking at the xHeapRegions structure in the debugger? It looks like it is taking the address of regionHEAP1_start not its value. I would do this

define regionHEAP1_start 0x10000000

xHeapRegions[0].pucStartAddress = (unsigned char*) region_HEAP_1_start; The other thing to do would put some code in heap_5 so you can break when the memory returned is out of bounds: if( returned address < min address OR returned address > max address ) { asm volatile(“NOP”); // Line for break point } when the break point is hit look at the variables in heap_5 to see why it was out of bounds. If you define configASSERT() it might trap an invalid vPortFree call, which might be the problem.

heap_5 allocating outside of allowed range

Still getting these issues. The compiler is IAR 7.4. The heap regions are initialized correctly. I even reduced the upper limit to account for heap bugs… In the last crash I got I had a hard fault within memcpy. When I the registers I got r0 = 0x10010001. This is outside the range of the heap which the upper limit is 0x1000FF00. This behavior is observed randomly after our PC connects to the board and configures the behavior of the application. During this phase tens of small messages are sent to the application, and many memory allocs and deallocs are called. Once the first phase is complete the application is stable, but the instability of the first phase is a critical issue for us. BTW, I switched to heap5 from heap4, and never observed these faults before, which leads me to the conclusion that this is specific to heap_5.

heap_5 allocating outside of allowed range

My reaction would be: Make absolutely sure that your application never writes to unallocated memory. If you malloc N bytes, do not use N+1 bytes. If you are not sure if memories get overwritten, as a test, malloc() more than you need and see if the extra bytes are still untouched before calling ‘vPortFree()’. r0 = 0x10010001 ? Beside being outside the memory, it is an unaligned address. Sometimes I saw memcpy() crashing because it was replaced (optimised) by ‘inline’ instructions performing 32-bit operations on a non-aligned address. I’m not sure if IAR would do the same. In GCC this problem can be avoided by using the compiler flag ‘-fno-builtin-memcpy’. The memcpy() function is always safe to call, also for unaligned addresses. Regards.

heap_5 allocating outside of allowed range

That is a good observation, although heap4 and heap5 are almost identical when it comes to allocation and free algorithms. The main different between the two is their initial state – before anything has been allocated. Do you ever call these functions from an interrupt? Regards.

heap_5 allocating outside of allowed range

r0=0x10010001 is probably a temporary address that was used by memcpy until it crashed. I think it’s safe to assume that the allocation routine did not return this address by itself. I did saw malloc returning address 0x10010000 and 0x20020000 (which is the other segment top address) several times. That’s why I lowered the upper limits…. As for use of the mallocs, I’m 99.999% sure that I don’t malloc in ISR. I’ll have to review the code, but I’m aware this is a huge no-no, and try to statically allocate/preallocate memories used in ISR. Secondly my application is 95% C++. I overloaded all required prototypes of the “new” operator to use pvPortMalloc and vPortFree. I always access pointers to classes and I never deal directly with pointers to allocated buffer, therefore I find it hard to believe that I overwrite the end of the allocated buffers. Again, I never observed these memory overwrites/hard faults/whatever when I used heap_4.