How to configure heap and stack sizes in MCUXpresso

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to configure heap and stack sizes in MCUXpresso

Jump to solution
9,118 Views
matheus_pinto1
Contributor II

Hi,

I am using MCUXpresso IDE v11.0.0_2516, the FRDM-K22F board and the FreeRTOS 9.0.0 port that comes with SDK.

In the application I am developing, I have no space for creating new dynamic data. So, the first step was increasing the heap size on "Project->Properties->C/C++ Build->Settings->MCU C++ Linker->Managed Linker Script" as in figures below.

pastedImage_1.png

The default value that is set is 0x1000 for the heap and 0x1000 for the stack. I set a breakpoint on pvPortMalloc, so I can see the first time that it is called. The "xFreeBytesRemaining" variable wich has the available memory remain is "10224" in first call.

However, when I tried to increase the heap size (let's say heap 0x1600 and stack 0x400) nothing happens. The "xFreeBytesRemaining" remains "10224" and application is stuck in same point.

Any tips on what is happening, and what can be done?

Thanks!

0 Kudos
1 Solution
8,483 Views
matheus_pinto1
Contributor II

I solve my problem!

Firstly, FreeRTOS does not use the heap or stack defined in the linker. Normally, this heap is set to zero and the stack value set to a minimum for main function use.

Using the "Heap 4" option, the "heap_4.c" file located at "freertos->portable" within the project directory, the heap is declared as a global variable like this:

static uint8_t ucHeap [configTOTAL_HEAP_SIZE];

Therefore, you can increase the size of the heap used by FreeRTOS through the configTOTAL_HEAP_SIZE macro in the FreeRTOSConfig.h file. Using the default memory settings available in "Project-> Properties-> C/C ++ Build-> Settings-> MCU C++ Linker-> Managed Linker Script" and increasing the size of this heap, the program will not compile because the ucHeap variable will exceed the SRAM UPPER (which is not allowed). For a value of ucHeap equal to 51200 bytes, in my case, is generated the following memory usage:

Memory region                Used Size      Region Size   %age Used
PROGRAM_FLASH:       216492 B       512 KB           41.29%
SRAM_UPPER:              71516 B         64 KB             109.12%
SRAM_LOWER:             0 GB              64 KB             0.00%

make: *** [makefile:55: HartROS_v3.axf] Error 1
"make -r -j4 all" terminated with exit code 2. Build might be incomplete.

To get around this, my way out was to put the global variables (and hence ucHeap) in SRAM LOWER with all its space available for storage. For this, in "Project-> Properties-> C/C ++ Build-> Settings-> MCU C++ Linker-> Managed Linker Script" the "Global data placement" field was changed from "default" to "SRAM LOWER" as presented in figure below.

global_sram.png

Now my program compiles correctly after increasing the heap to 51200 bytes. The memory usage output was as follows:

Memory region               Used Size      Region Size   %age Used
PROGRAM_FLASH:      216492 B       512 KB           41.29%
SRAM_UPPER:             8 KB               64 KB             12.50%
SRAM_LOWER:            63324 B         64 KB             96.62%

Finished building target: HartROS_v3.axf

View solution in original post

3 Replies
8,484 Views
matheus_pinto1
Contributor II

I solve my problem!

Firstly, FreeRTOS does not use the heap or stack defined in the linker. Normally, this heap is set to zero and the stack value set to a minimum for main function use.

Using the "Heap 4" option, the "heap_4.c" file located at "freertos->portable" within the project directory, the heap is declared as a global variable like this:

static uint8_t ucHeap [configTOTAL_HEAP_SIZE];

Therefore, you can increase the size of the heap used by FreeRTOS through the configTOTAL_HEAP_SIZE macro in the FreeRTOSConfig.h file. Using the default memory settings available in "Project-> Properties-> C/C ++ Build-> Settings-> MCU C++ Linker-> Managed Linker Script" and increasing the size of this heap, the program will not compile because the ucHeap variable will exceed the SRAM UPPER (which is not allowed). For a value of ucHeap equal to 51200 bytes, in my case, is generated the following memory usage:

Memory region                Used Size      Region Size   %age Used
PROGRAM_FLASH:       216492 B       512 KB           41.29%
SRAM_UPPER:              71516 B         64 KB             109.12%
SRAM_LOWER:             0 GB              64 KB             0.00%

make: *** [makefile:55: HartROS_v3.axf] Error 1
"make -r -j4 all" terminated with exit code 2. Build might be incomplete.

To get around this, my way out was to put the global variables (and hence ucHeap) in SRAM LOWER with all its space available for storage. For this, in "Project-> Properties-> C/C ++ Build-> Settings-> MCU C++ Linker-> Managed Linker Script" the "Global data placement" field was changed from "default" to "SRAM LOWER" as presented in figure below.

global_sram.png

Now my program compiles correctly after increasing the heap to 51200 bytes. The memory usage output was as follows:

Memory region               Used Size      Region Size   %age Used
PROGRAM_FLASH:      216492 B       512 KB           41.29%
SRAM_UPPER:             8 KB               64 KB             12.50%
SRAM_LOWER:            63324 B         64 KB             96.62%

Finished building target: HartROS_v3.axf

8,483 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Since you're using a FreeRTOS-based project, your change will obviously not help. You're changing the heap size used by the standard C malloc whereas FreeRTOS uses its own memory allocation scheme. If you'll carefully inspect the implementation of prvHeapInit, you'll notice that the total heap size is set to configTOTAL_HEAP_SIZE (which is actually hardcoded to 10K in FreeRTOSConfig.h). This is what you need to change.

The initial stack size should be correctly controlled by the setting you mentioned. The initial MSP is set to _vStackTop that's depending on _StackSize. Check the linker script. Regarding the stack size allocated to a task, isn't that configured/specified when you create the actual task? I don't have much knowledge of the FreeRTOS code itself.

Greetings,
MCUXpresso IDE Support

3,254 Views
brianknittel
Contributor II

FYI - The responses here are correct only if you are using the FreeRTOS "heap4.c" implementation, where freeRTOS allocates memory from a static buffer. If you use "heap3.c", it uses the C library's malloc(), and these answers re not correct. Heap3 uses the heap as configured by the MCUXpresso linker. As far as I can see, if you are using the "MCUXpresso Style" heap and stack placement method, it's not easy (or maybe it's not possible) to assign a fixed stack size and then have the heap use "everything else."