2014-11-25 06:39 AM
Hello everyone,
we got a project where we need literally any space available for dynamic heap allocation.So we now switched from a F2 to a F4 setup, because it has more RAM. We are using the STM32F427 at the moment. As I learned now the RAM doesn't just get bigger but now has seperate RAM regions, which are organized by KEIL via IRAM1 and IRAM2 sections (192kB and 64kB).So now my question, is it possible to really use every bit of free space for the heap management, basically splitting it up into the remaining IRAM1 and all of IRAM2?Any help is apreciated!Patrick2014-11-25 07:04 AM
Patrick,
SRAM on F4 are separated, not to disturb the programmer, but because they are of different kind. The main 192KB is connected as a bus slave, which mean that it canbe the target fo the CPU and DMA as well. The other 64Kb is only connected to the CPU (Core Coupled Memory), which prevent them to be used as DMA source/target. Of course you can use a heap allocator that knows both banks and allocates bits in either according previous allocation and free space. But this scheme forgets about the nature of CCM and can lead to misuse (DMA+CCM won't work). A typical design is to use CCM for thread stacks or computing only data buffers (example: zlib or jpeg buffers), and having a heap allocator for the rest of 192Kb of SRAM. -- Laurent2014-11-25 07:35 AM
You'd need to refactor or modify the allocator routines. Break out your CS textbooks.
You might want to consider other allocation schemes, allocating from different, or fixed pools. If you're critically dependent on dynamic allocation, watch for fragmentation issues, which are likely to bring the system to it's knees long before the memory runs out.2014-11-25 01:17 PM
Hey guys,
thanks for your quick replies.@ laurent: Thanks for your clarification, I already got aware of that though. Just wasn't used of that layout from my experience with F1 or F2 devices. It's pretty neat actually, but unfortunately not in that particular use case of mine.Objects allocated at the heap aren't accessed by the DMA at all, so that won't be a problem.@clive: Thanks, I already thought about other ways of doing it, but I'm facing an already established system and I'm just tryin to adept it most efficiently. Fragmentation shouldn't be a concern, because everything is allocated at startup initialization. Problem is though, that I can't say what I'm allocating, because that is provided by custom user data (hope that isn't too confusing, sorry for the english though)but you are already pointing me in the right direction with rewriting or extending the allocation process. That's exactly what my original intention was, trying to ask if someone has already experience which such things on an F4 controller or knows on what to take caution (like your hint with DMA and CCM).So far thank you guys!2014-11-25 09:46 PM
Based on my understanding of the allocator I might use the following to make a ''free list'' that spans a number of discontinuous memory regions.
#include <
stdlib.h
>
/**************************************************************************/
// Keil uv4 MICROLIB compatible heap initialization
extern unsigned long __microlib_freelist;
extern unsigned long __microlib_freelist_initialised;
extern unsigned long __heap_base;
extern unsigned long __heap_limit;
/**************************************************************************/
void add_heap(unsigned long addr, unsigned long size) // sourcer32@gmail.com
{
unsigned long *p = (unsigned long *)addr;
unsigned long span;
size >>= 2; // size in 32-bit words
size -= 2; // two words used for internal structures
if (__microlib_freelist_initialised == 0) // free list created yet?
{
__microlib_freelist_initialised = 1;
__microlib_freelist = 0;
span = 0;
}
else
{
span = __microlib_freelist - addr - (size << 2); // faux allocation across the discontinuity
}
p[0] = size << 2; // size of list entry
p[1] = __microlib_freelist; // next entry
p[size] = span;
p[size+1] = 0; // terminal value
__microlib_freelist = addr; // current entry
}
/**************************************************************************/
void alloc_heaps(void) // Called prior to any malloc()
{
// Enumerate available heap memory regions in DECENDING memory order
//add_heap(0xD0000000, 0x800000); // SDRAM 8MB - Must be initialized
add_heap((unsigned long)&__heap_base,(unsigned long)&__heap_limit - (unsigned long)&__heap_base); // Classic HEAP section
// add_heap(0x20004000, 0x14000); // SRAM (PORTION OF)
add_heap(0x10000000, 0x10000); // CCM 64K
}
/**************************************************************************/
2014-11-26 01:04 AM
Thank you Clive, that seems to be exactly what I need. And sorry that this seemed to be rather an ARM related question than ST. But nevertheless you helped me a lot!
2014-11-26 08:34 AM
Thank you Clive, that seems to be exactly what I need. And sorry that this seemed to be rather an ARM related question than ST. But nevertheless you helped me a lot!
That's Ok, ST parts only represent a small subset for my programming experience.