Stock FreeRTOS on Cortex M0 Not Enough Memory with 4kb?

leroy105 wrote on Monday, January 22, 2018:


I have some experience coding 8 bit MCUs. I just am learning Cortex M.

I started with FreeRTOS from the official source, on a STM32 4kB M0. At first I had some issues with heap allocation and getting everything to compile. It’s my first time working with dyanmic memory allocation.

Anyway, I got everything compiling and have all the correct portables linked together on the 4kB STM32 M0.

When I go to create a task, I get the malloc error, from tasks.c I tried a few versions and went over everything in the MAP file.

It seems like at compile time, I have 1kB of RAM left (we have the STM32 peripheral drivers + CMSIS-Core + FreeRTOS & HEAP (1kB) in RAM at compile time). I think 1kB is sufficient to create a task. I can initialize the kernel, but when I go to add tasks it returns the malloc error.

I noticed that on the 4kB M0, I can also get FreeRTOS running with the official STM Cube FreeRTOS + CMSIS API port. Clearly a lot of work was done to get the CMSIS-API calls wired in.

I made sure to copy stack and heap settings from the STM port from the Cube, in case I am overflowing something. It made no difference, I will will get the malloc error when I go to create a task.

Ostensibly, that heap area is already carved out of memory at compile time so it should be there… right?

I have an 8kB STM32 CM0 development board lying around, and copied over the CM0 portables. Everything works great. So I am calling that I passed the “idiot” test…

Is there a lot of optimization and changes to FreeRTOS to get it work on a 4kB STM32 CM0? More generally, any 4kB CM0?

Am I missing something obvious, or is 4kB just too little without some major work?

leroy105 wrote on Monday, January 22, 2018:

UPDATE: Okay, so I still get the malloc error on the 4kB, but it was working for a little. I saw this a day ago. It was initializing a task while I was debugging the code, and then started throwing the malloc error.

Could this be some kind of fragmentation issue? I’m using Heap1. I loosely understand the differences betwen the heap strategies.

I’m not on drugs… this worked for a bit at initializing a task on the 4kB, and then started throwing errors again.

rtel wrote on Monday, January 22, 2018:

Don’t forget that when you start the scheduler FreeRTOS will also create
the idle task, and may (depending on the configUSE_TIMERS setting)
create the timer/RTOS daemon task. The size of the stacks used by those
respectively (from memory, I may have the names slightly wrong).

You cannot fragment with heap_1 because that allocator does not allow
memory to be freed.

You can of course set configSUPPORT_DYNAMIC_ALLOCATION to 0 and
configSUPPORT_STATIC_ALLOCATION to 1 to create a completely statically
allocated system, without a heap at all. Don’t forget to set the heap
defined by your compiler/linker to 0 too.

leroy105 wrote on Monday, January 22, 2018:

Richard – yes, I hear you loud and clear on heap_1. Why it was working earlier, is a mystery to me.

Once it started tossing errors, I actually see that it is choke’ing up on the kernel initalization not the task now.

I’ll try the static approach. I need to dig through the documents how that is all pieced together.

I don’t immediately see a configTIMER_TASK_STACK_SIZE. I’ll do some digging because it is choking up there.

I mean, I see a minimal footprint before (CMSIS alone, is 1.5kB, out of 4kB, the peripheral drivers seem like another 1kB I think). Maybe it is a pipedream on a 4kB MCU! :wink:

If I get it going on 4kB, I’ll post back.