pvPortMalloc and vPortFree Usage (Heap4.c) in Baremetal STM32F407ZETx

Hi All,

I have had a good experience in programming bare metal stm32f4x; however, i tried to shift my code to freeRTOS and for that i first wanted to see if i can use Heap4.c for memory allocation instead of standard C malloc and free calls to better manage the memory etc.

However, what I observed is that using these calls disables my interrupts and never turns them back on. Hence, anything which makes use of interrupts is not working; everything else, which has nothing to do with interrupts is working ok. Not even Systick timer interrupt handler is being triggered.

So, the question is that, how can we make use of pvPortMalloc and vPortFree with bare metal code considering that all other peripherals do make use of their interrupts and SysTick is basically used for simple time delays etc. When using these calls, I could not see any prints happening inside systick as there was no systick handler being called.

Here I would like to point out that I am not calling pvPortMalloc or vPortFree in any interrupt context at all. So, that is totally safe and nothing to worry about that.

I have read through few discussions and if i understand correctly, then any call to FreeRTOS scheduler to suspend tasks etc does not impact as there will be no tasks at all. So, I expect this heap4.c port to work just fine with bare metal as well as long as we stay away from using them within ISR context; but apparently it just disables interrupts and seem to never turn them back on.

I hope to have the opinion of experts here on using pvPortMalloc and vPortFree in bare metal instead of using freeRTOS.

Best regards,
Junaid

If you want to use those functions outside of FreeRTOS remove the calls to suspend and resume the scheduler. Those will disable interrupts if FreeRTOS hasn’t been started.

Shouldn’t the call to resume scheduler enable the interrupts if call to suspend disables interrupts? That is my question basically. That if it disables interrupts, then why resume call does not enable the interrupts if it does so. Or is there an extra check with resume call, to see if scheduler is running, to enable the interrupts? If that is so, then i can imagine that extra check is hindering enabling of interrupts. if not, then I dont get the logic to comment out these calls.

This is where we end up at the end of pvPortMalloc and vPortFree:

image

And at the end of this call we reach here:

And finally this assembly instruction here:

I expect this to enable all interrupts back. Is there anything I am missing here?

Why not just stepping thru the code with the debugger to verify ?
And why bother using FreeRTOS calls if not using FreeRTOS at all ?
Just get rid of it as Richard proposed if you really want to use FreeRTOS heap_4 or stick to default newlib malloc.

Looks like you did not properly read my post and replied code snippets where it clearly shows what I expected to see. In this case, stepping through the code via debugger does not add much. I don’t understand much of assembly, that is why I was expecting a better reply in terms of what could be the behavior in the context of what I explained. What you are suggesting is something I already know.

What richard has suggested is simple commenting out of two calls, but the point is why the existing calls don’t work since they simply turn back the interrupts on when it exits vPortExitCritical as i have shown above.

Well, I do understand what you want to do - I just don’t get why :wink:
Good luck :+1:

As I explained before, better memory management. For example, one of the main objectives is to have fragmentation removed. Because of memory fragmentation I cannot allocate the memory at some point even though as a whole i do have more than what is required.

One of the things to consider is that the uxCriticalNesting Variable may be uninitialized, and thus ExitCriticalSection() may never take the branch to eventually restore the interrupt mask. I assume you verified that you indeed end up in vPortSetBasePRI() with the parameter set to 0?

Depending on what IDE you use, it may be very straightforward to inspect the basepri register after the instruction was executed. If it’s indeed 0 but you still don’t get interrupts, then you are barking up the wrong tree (I’m sure you know that the Cortex M defines several conditions that need to be true for interrupts to get asserted, so we may be looking at side effects of other pieces of code here).

Other than that, I’d agree with Richard; these calls are specifically and explicitly made to enforce serialization in a multitasking environment, so if you wish to re-use the memory manager outside of that environment, you need to manually remove ALL code that relies on or assumes the presence of an OS. There may be more, I don’t have access to the code right now.

BTW I would consider it as a significant compliment to the author(s) of heap_4.c if anyone thinks that it would implement a better memory manager that the C runtime routines as the latter ones have been under development for decades now…

Thank you for explaining. Now that I have a more elaborated view I will try commenting them out. And, as you said, I believe heap4/5.c are definitely appreciable as i have extensively tested standard C malloc and it leave memory fragmented which is hugely inefficient.

FreeRTOS deliberately leaves interrupts disabled between the first call to an API function and the kernel being started. Therefore, you cannot use the memory allocator in place of the standard C malloc and free unless the scheduler has started. I think there is an FAQ on the reasons for this somewhere - but in summary this is done because one of the biggest causes of support requests in early versions of FreeRTOS was people setting up interrupts before starting the scheduler (which is a normal thing to do) but then those interrupts executing and attempting to use the scheduler (also before the scheduler was started) resulting in inexplicable crashes.

Just updating… Yes, richard’s suggestion works and the rationale is explained above by RAc.

Now to show the effect of using heap4.c here is the sample image::

Now, in this image, this yellow highlighted part was never successful due to insufficient memory caused by memory fragmentation. now with heap4.c usage, not using FreeRTOS while following richard’s suggestion, i can easily allocate this memory as well since there is no fragmentation after freeing above 32KB.

I basically have my own little kernel / scheduler for non-preemptive task execution where my systick routine takes around 2.6us for counter increment and then i execute the tasks with respect to their readiness and priority in the main loop. The only remaining thing was proper memory usage which is now achieved using heap4.c.

@RAc @rtel Thank you for explanation. and richard-damon Thank you for the suggestion.