STM32, Startup files and FreeRTOS

Hi Folks,


I have a STM32 project with the regular startup_xyz.s file which has the STACK, HEAP definitions.

My question is a bit quite fundamental. Now, FreeRTOS likes to have the memory segments defined and exported via vPortDefineHeapRegions()

How does that pan out with the startup_xyz.s file ?
(I mean there are 2 definitions, now. Maybe it is a stupid question altogether. But my mind is in a state of confusion)



The FreeRTOS kernel does not call malloc() and free() directly, but pvPortMalloc() and vPortFree(). You can define these to do whatever you want, although in nearly all cases you will use one of the heap implementations provided by FreeRTOS. See On that link, if you use anything other than heap_3.c, the kernel will not use the heap allocated by your startup code, and if nothing else does, then there is no point allocating a heap in the start up code at all. The only heap implementation that uses vPortDefineHeapRegions() is heap_5, and that is only necessary if you want your heap to be spread across more than one memory block. The information you need should be on the link above.

The startup files only set the initial stack, which is used while running main. Often its location and size are determined in the linker file.

I see that the word HEAP also occurs, but I think it can be ignored. That would be the heap as used by the standard malloc()/free(). In my example it gets a size of 512 bytes.

The use of vPortDefineHeapRegions() ( heap_5.c ) is not obligatory, but it is very handy. Only after compiling and linking the project, you know how much heap is left.

The stack of the tasks will be malloc’d by FreeRTOS, using pvPortMalloc()/vPortFree(). The size of those stacks is determined by the programmer.

Hi Richard,

Thanks for the quick response.

I am having a H7 MCU with 5 different memory blocks, so heap_5.c is the way to go, from what you say and what I read as well.

I almost got what you meant. ie, Unless I am using heap_3.c there’s no point in having a heap allocated in the startup code.

Ok, the best possibility is to use a minimal heap to bootstrap the kernel ?
(ie let FreeRTOS manage stack/heap ?) (Once the kernel is up, user application then need not bother with the stack/heap allocation in the startup file ?)



Hi Hein,


Ok, so you keep the minimal possible HEAP in the startup file ?
(And let FreeRTOS manage the rest ?)

Yes, I understand what you are saying. Identifying the application size is quite helpful.
Ok. So, what you mean: Have a minimal startup, do all the work in the task. -> Task stack size will be malloc’d by the user.

Sounds fine. Cool. Thanks for the simplistic explanation.
(In fact, I was fiddling with your tree. In fact, I was wondering whether to post the details on the forum, or in a private conversation. I am still not done yet.)



@manu, you will also want to review:

Last I checked, ST distribution (ie code framework generated from CubeMX) was extremely buggy and you will need some additional code…
Hope that helps,
Best Regards, Dave

You can use GNU LD --wrap feature to redirect malloc and free calls (if any) to pvPortMalloc and vPortFree:


Hi Gaurav,

I am using ARMCC MDK.


Hi Dave,

I read through the documentation on your website.
There was quite some info in there!

ST code was and is … … Sigh!
They have also some claims. Defending claims tooth and nail.
Everyone claims something or the other.
What about Datasheet bugs ? Argh!
(Recently posted one to them)

Don’t know what to say. I can only say, feeling tired and exhausted.

Other than bugs, there are bad decisions and such things too. These things exist everywhere, doesn’t apply to a single project/vendor. Look deeper, you see it everywhere.

I hear what you are saying. I am using MDK and it uses Micro LIB.
Don’t know whether the issue, you cited, applies there too …




Using the example, you have in:

I tried allocating a minimal STACK and HEAP within the startup_xx.s file.

Tried to keep it simple, by using the large memory block (AXI-SRAM) of 512kb,

But at link time, the linker could not fit the data in. I am wondering,
how to fit it all in.