non-contiguous heap definition for different types of memories

gezab wrote on Tuesday, August 30, 2016:

Hi,

I am working with IAR’s STM32F746 development board where I have 3 regions of RAM: 64k very fast access internal RAM (for internal variables and structures), 256k of fast access internal RAM (defined as heap as of now) and 32M of external SDRAM which is big but quite slow (currently taking 22 clock cycles at 216MHz for a 32-bit read operation as the board connects the SDRAM chip to the uC via a 16-bit data bus and bursts are not supported by the SDRAM controller). I want to have my heap extended in SDRAM, too, and this would actually be quite straightforward with heap regions introduced in heap_5.c… The problem is that i want to control at run time whether internal RAM or external RAM gets allocated when malloc is called (I need dynamic allocation for fast as well as for slow memories).

Is it planned to have such a memory allocation flavour, too, like heap_6.c maybe? At the moment I have tailored heap_4.c for internal RAM and heap_5.c for external RAM, but this is more like a dirty hack than a nice clean solution… I do not want to have modified FreeRTOS code in my project and I also would be happy to avoid having 3rd party malloc libraries.

Thanks for any ideas in advance and best regards,
Geza

davedoors wrote on Tuesday, August 30, 2016:

Perhaps use static allocation (xTaskCreateStatic(), xQueueCreateStatic(), etc.) for FreeRTOS objects to allow you to place structs and task stacks in internal RAM, then if your application calls pvPortMalloc() for other objects have heap_4/5.c use the external RAM?

Or wrap pvPortMalloc() and vPortFree() in your own API that redirects the allocation to fast or slow RAM depending?

Or have pvPortMalloc() use fast internal RAM for FreeRTOS objects, and then call normally malloc() for anything else and have that come from slow RAM?

gezab wrote on Tuesday, August 30, 2016:

Thanks for your rapid reply, Dave.

As a matter of fact, I already have static OS object allocation with
objects defined in IRAM1 (64k, very fast internal). I want to keep IRAM1
for statically allocated objects, IRAM2 (256k, fast internal) for
dynamically allocated objects (like file name lists, codec work areas,
etc.) and the ERAM1 (32M, slow external) for storing large amounts of data
like the input/output of codecs, pictures, web pages, etc.

My biggest problem with having both heap_4.c and heap_5.c is that I needed
to rename exported functions in order to avoid naming conflicts.

Do you think that it would be feasible and reasonable to keep the static
allocation scheme for OS objects, keeping heap_4.c for fast stuff and
wrapping standard library malloc and co. for external slow things (wrapping
is needed for thread safety, I thought of protecting function calls with
semaphores)? This way I would have control over memory types, I do not have
naming conflicts, the only drawback is code size as I have two independent
sets of allocation functions.

On Tue, Aug 30, 2016 at 3:00 PM, Dave davedoors@users.sf.net wrote:

Perhaps use static allocation (xTaskCreateStatic(), xQueueCreateStatic(),
etc.) for FreeRTOS objects to allow you to place structs and task stacks in
internal RAM, then if your application calls pvPortMalloc() for other
objects have heap_4/5.c use the external RAM?

Or wrap pvPortMalloc() and vPortFree() in your own API that redirects the
allocation to fast or slow RAM depending?

Or have pvPortMalloc() use fast internal RAM for FreeRTOS objects, and
then call normally malloc() for anything else and have that come from slow
RAM?

non-contiguous heap definition for different types of memories
https://sourceforge.net/p/freertos/discussion/382005/thread/1abe102d/?limit=25#80f9

Sent from sourceforge.net because you indicated interest in
SourceForge.net: Log In to SourceForge.net

To unsubscribe from further messages, please visit
SourceForge.net: Log In to SourceForge.net

rtel wrote on Tuesday, August 30, 2016:

Do you think that it would be feasible and reasonable to keep the static
allocation scheme for OS objects, keeping heap_4.c for fast stuff and
wrapping standard library malloc and co. for external slow things (wrapping
is needed for thread safety, I thought of protecting function calls with
semaphores)? This way I would have control over memory types, I do not have
naming conflicts, the only drawback is code size as I have two independent
sets of allocation functions.

Yes, sounds reasonable. You just need to make sure that your linker
script is able to place the heap in your large external memory.

gezab wrote on Wednesday, August 31, 2016:

Thanks, Richard. I converted my code as written above, it is fully
functional and works as desired.

Just for my own information, would you also consider introducing a new
memory allocation flavour like I described in my previous email? That is,
on top of having a bunch of HeapRegion_t descriptors, introducing a second
level of grouping (e.g. HeapRegionGroup_t) and the ability to control which
group pvPortMalloc() will allocate memory from.

On Tue, Aug 30, 2016 at 5:19 PM, Real Time Engineers ltd. <rtel@users.sf.net

wrote:

Do you think that it would be feasible and reasonable to keep the static
allocation scheme for OS objects, keeping heap_4.c for fast stuff and
wrapping standard library malloc and co. for external slow things (wrapping
is needed for thread safety, I thought of protecting function calls with
semaphores)? This way I would have control over memory types, I do not have
naming conflicts, the only drawback is code size as I have two independent
sets of allocation functions.

Yes, sounds reasonable. You just need to make sure that your linker
script is able to place the heap in your large external memory.

non-contiguous heap definition for different types of memories
https://sourceforge.net/p/freertos/discussion/382005/thread/1abe102d/?limit=25#80f9/820f/4521

Sent from sourceforge.net because you indicated interest in
SourceForge.net: Log In to SourceForge.net

To unsubscribe from further messages, please visit
SourceForge.net: Log In to SourceForge.net

rtel wrote on Wednesday, August 31, 2016:

Controlling which group an allocation came from would presumably need an
additional parameter to the allocation function - so I’m not sure how
practical that would be internally for the OS without breaking backward
compatibility, or without breaking the semantic similarity between
pvPortMalloc()/vPortFree() and malloc()/free().

I think this could be done externally, at the application level though,
for those few that need it. So there would be a wrapper around the
pvPortMalloc() and vPortFree() functions that chose which memory
allocator to use - the issue would then be how to get around having
multiple definitions of the allocation functions themselves.

richard_damon wrote on Wednesday, August 31, 2016:

The amount of code needed for duplicate inplementations of malloc and free is pretty small, especially for systems that would need this sort of functionality, which by definition have multiple ram segments. Having your own private fork of the memory allocation functions (copied from the standard FreeRTOS functions and given a new function name) shouldn’t add that much work, as these functions have been fairly stable, so little need to migrate updates. Any method I can think of to make this general purpose so as to be part of the official port seems to add overhead to the simple case or breaks backwards compatibility which isn’t desired. It also is very liey possibile that different memory regions will want differant stratagies for the allocation method (the small, very fast memory might be best with a static, zero overhead method, the very large but slow memory may need the full allocation/deallocation capability).