My customer is beginning a new project with MKL25Z128VLH4. The IDE used is KDS 3.x, KSDK 1.3 and he is using FreeRTOS.

We both are new to FreeRTOS, so we are still facing some difficulties during this learning process.

He created two tasks of same priority level through Processor Expert. For a test, we just increment two global variables. As we debug the project, we see that Task 1 is created, but Task 2 is not. Going in deeper debugging, we found out that Task creation function returns a memory allocation error. If we increase the tasks stacks sizes from 1024 to 2048, not even Task 1 is created.

When we decreased stacks sizes from 1024 to 512, both tasks run, but if we created the third task, this last one are not created, and returns the error I commented above.

I increased the heap size as Daniel suggest but also did a few other things you might be interested in.

I had debugged the code and memory map to see that the FreeRTOS application is using the HEAP for alloc/free (heap_3.c) operations. With the default Stack and Heap sizes, the Heap was crossing the two SRAM block boundary of 0x2000_0000. This can cause issue is an access occurs across the boundary. Also the Stack wasn't really be used much. So I increased Heap and decreased Stack size.

I adjusted the heap and stack size in the PE CPU Component -> Build options tab as follows:

The Heap still had issue of crossing the SRAM boundary so after generating the linker file, I then un-checked the "Generate linker file" in the Build options tab and then modified the ProcessorExpert.ld linker file as shown below:

.stack :

{

. = ALIGN(8);

. += STACK_SIZE;

} > m_data

.heap :

{

. = ALIGN(0x20000000);

__end__ = .;

PROVIDE(end = .);

__HeapBase = .;

. += HEAP_SIZE;

__HeapLimit = .;

} > m_data

This modification switched the Heap and Stack memory map locations so the "small" .stack was below 0x2000_0000 and .heap started at 0x2000_0000.

I then was able to add in more OS_Task and play around with increasing the stack size for them and get them to successfully run.

I learned that just initializing FreeRTOS before creating any user tasks uses up 2880 bytes (assuming I calculated correctly). This leaves about 9400 bytes for user.

The overhead hidden tasks are IDLE, TmrSvc, along with their respective TCB structures.

I lowered even more all tasks stacks sizes and increased the total heap size and everything is working now.

But I don't understand. When main_task stack size was 1024 bytes and the other three tasks stacks sizes were 512 bytes each, the third task was not created, because it could not allocate memory for it.

By my count, if total stack size is set to 0x1000 and the stack consumed by the tasks is 2560 bytes, we would still have 1536 bytes left, right? So, why the third task got out of memory allocation?

What is the heap for? Does it take RAM memory as the stack? What is the difference between heap and stack?

Is there a way to know exactly how much each task is taking from RAM and Flash memory and how much is left?

I increased the heap size as Daniel suggest but also did a few other things you might be interested in.

I had debugged the code and memory map to see that the FreeRTOS application is using the HEAP for alloc/free (heap_3.c) operations. With the default Stack and Heap sizes, the Heap was crossing the two SRAM block boundary of 0x2000_0000. This can cause issue is an access occurs across the boundary. Also the Stack wasn't really be used much. So I increased Heap and decreased Stack size.

I adjusted the heap and stack size in the PE CPU Component -> Build options tab as follows:

The Heap still had issue of crossing the SRAM boundary so after generating the linker file, I then un-checked the "Generate linker file" in the Build options tab and then modified the ProcessorExpert.ld linker file as shown below:

.stack :

{

. = ALIGN(8);

. += STACK_SIZE;

} > m_data

.heap :

{

. = ALIGN(0x20000000);

__end__ = .;

PROVIDE(end = .);

__HeapBase = .;

. += HEAP_SIZE;

__HeapLimit = .;

} > m_data

This modification switched the Heap and Stack memory map locations so the "small" .stack was below 0x2000_0000 and .heap started at 0x2000_0000.

I then was able to add in more OS_Task and play around with increasing the stack size for them and get them to successfully run.

I learned that just initializing FreeRTOS before creating any user tasks uses up 2880 bytes (assuming I calculated correctly). This leaves about 9400 bytes for user.

The overhead hidden tasks are IDLE, TmrSvc, along with their respective TCB structures.

I've attached my modified version of the project for you.

Regards,

David

Attachments

You may also consider using one of the heap implementations provided by freertos (particularly heap_4). Another tip is to use the FreeRTOS PX component published by MCUOnEclipse which allows for heap configuration via the component inspector like this:

What you just told me is a kind of bug or it is a feature of FreeRTOS KSDK library? Because we just made a test in CodeWarrior 10 with MQX-Lite and this problem never happens and all this adjustment is not necessary.

You taught me some more things I didn't know about FreeRTOS. I must confess I have too much to learn yet! So does the customer. I and the customer are still beginners in FreeRTOS.

Could you please answer me some more questions that came to my mind?

I noticed you kept the same stack size (512 bytes) as you first set in Processor Expert.

What is the difference between heap and stack? I noticed that the sum of heap and stack sizes must not surpass the total RAM size, right?

When you create a new task and set its stack size, this stack actually consumes heap and not stack from RAM memory?

How can I manage all this to know how much heap and stack each task is consuming and how much stack I must set in the tasks creation?

I don't have words to thank you for your attention and help! I really appreciate it!

Correct me if wrong but I think you directed the questions to me (David)?

Assuming so my answers are below. If I am wrong then stop reading and wait for Jacob to reply ;-)

I am not expert with FreeRTOS but learning everyday. Glad to have helped and look forward to more. Answers to the best of my ability follow:

Q1) What you just told me is a kind of bug or it is a feature of FreeRTOS KSDK library?

A1) Think more of a feature. As the PE and KSDK team create and test they are doing the best they can and probably assume that if the tools/examples work for a larger device (K64 with 1MB flash and 256KB SRAM) then they should scale and work with smaller memory devices. In your case with KL25 is pretty SRAM constrained and think the memory map needed the tweaks I added to make it work more reliably. But I will ask our team to review and see if they might take this tweak into consideration.

Q2) I noticed you kept the same stack size (512 bytes) as you first set in Processor Expert.

What is the difference between heap and stack? I noticed that the sum of heap and stack sizes must not surpass the total RAM size, right?

A2) FreeRTOS with heap_3 configuration is using the heap to alloc/free memory for the RTOS. So as tasks are created, then request memory from the heap to use for tasks stacks and other resources. I think the stack (512) is only used for getting system started but I am not 100% sure and need to dig into this myself.

Q3) When you create a new task and set its stack size, this stack actually consumes heap and not stack from RAM memory?

A3) Correct! But this is for the heap_3 case and I haven't played with the other heap options so they may differ.

Q4) How can I manage all this to know how much heap and stack each task is consuming and how much stack I must set in the tasks creation?

A4) Great question. It really has been done by blood/sweat/tears and experimentation by setting stack size high to start and reducing it later to optimize. Future tools will help to visually do this. Reference this great post (and sign up for it).