Put heap in external memory for STM32

glory1978 wrote on Wednesday, May 02, 2012:

Hi all!
Tell me please, is it possible to put FreeRTOS’s heap in to external memory.
I have stm3240g-eval board with 2M external (off-chip) memory. I would like if somebody points me how can I change linker and stm32-startup files for my purposes.
Maybe, there is somebody - how solved a similar problem.

I tried to make changes myself.
I added in ld-file new memory region: EXT_RAM (rxw)    : ORIGIN = 0x64000000, LENGTH = 2048K; added new section - RTOS_HEAP.
For xHeap add attribute-> __attribute__ ((section (“RTOS_HEAP”))) static union xRTOS_HEAP{…} xHeap;
In startup file add FSMC initialization as described in stm examples.
After that when sheduler started program goes to this line in vPortStartFirstTask:
    " svc 0 \n" /* System call to start first task. */
and stay at this line
What I missed ?

Thanks in advance.

rtel wrote on Wednesday, May 02, 2012:

I’m assuming you are using heap_1.c or heap_2.c, in which case the heap is just an array, I think call ucHeap;  If so, there are two things you can do.

1) Create a linker section of the size you require to hold the heap, then use the compilers language extensions to force the ucHeap array into that section.  How this is done depends on the compiler you are using, as each has its own linker script syntax and compiler extensions.

2) Define ucHeap as a pointer, instead of an array, and then just set the pointer to a region of RAM you have allocated for the purpose in your linker script.  You will also need to define how big the region is.


glory1978 wrote on Thursday, May 03, 2012:

Thanks for response.
But there is a problem.
I tried to create simple project. There are 3 arrays:
- one in internal RAM ( defined like uint32_t Tab );
- two - in external ( defined like  __attribute__ ((section (“RTOS_HEAP”))) static uint32_t ext_var ).
Also I changed linker file and cpu-startup file. In function main() I fill in Tab array with incremented data, ext_var1 array filled with values from Tab-array, ext_var2-array filled with values from ext_var1 + constant. And all workes fine - all values in arrays are correct.

I used same linker- and startup- files in FreeRTOS application, xHeap defined in external memory with ‘__attribute__ ((section (“RTOS_HEAP”)))’-contruction {same as in my worked project}. But there is problem - described above: when first task started  - application stopped in line “svc 0” of vPortStartFirstTask function.

rtel wrote on Thursday, May 03, 2012:

- Do you get past svc 0 when the heap is in internal RAM?
- Are you using the same start up code in both FreeRTOS and non FreeRTOS versions?
- Which heap file are you using, heap_1, heap_2 or heap_3, and what changes did you make to them?


glory1978 wrote on Thursday, May 03, 2012:

1. There aren’t problems when heap located in internal RAM - OS worked.
2. In both applications used same startup and linker files.
3. I use heap_2, and only one change I made - is point xHeap to external RAM -> __attribute__ ((section (“RTOS_HEAP”))) static union xRTOS_HEAP{…} xHeap;

I return to worked version of application - with heap located in intRAM and STM32 files (linker and startup).
Now I make some changes:
1) in linker file added new memory region (for external RAM) and section pointed to this region; in startup file - added initialization of FSMC - all workes.
2) add array __attribute__ ((section (“RTOS_HEAP”))) static uint32_t array pointed to external RAM; add new task where this array filled and in infinite loop readed - all workes.
3) add __attribute__ ((section (“RTOS_HEAP”))) for static union xRTOS_HEAP{…} xHeap - which points xHeap to external RAM - Hard fault occurs - LR-register has value 0x8000800 - that points to address to which execution need to return - I examine listing file and find that this address is one of the commands of _malloc_r functions.

davedoors wrote on Thursday, May 03, 2012:

When does the hard fault ocur though? When you try and allocate from the RAM, or when you try and run a task whose stack is located in the RAM. An array of 1024 is extremely small, are you checking for heap overflows, and that xTaskCreate() or a queue or semaphore create function is not returning null?

glory1978 wrote on Thursday, May 03, 2012:

I could not find when hard fault occured, yet. All semaphores, queues defined correctly - their address in external memory, create functions returned - pdPass.

glory1978 wrote on Friday, May 04, 2012:

This is very strange.
I created simply application based on previous configuration of linker and startup files. xHeap define in external memory.
In application I create 2 tasks and queue. One of application configure eval-board keys, check their status and send to queue. Another task configure eval-board leds, receive message from queue and blink leds in dependence of key state. And this application work.

But when I insert in second application initialization of eval-board LCD (which also use FSMC, as an external SRAM) application doesn’t work - hard fault occurs.

cahbtexhuk wrote on Tuesday, December 04, 2012:

I have a similar problem. I am using LPC1768, which has 64k RAM (32k primary and 32k AHB RAM), as stated in datasheet, FreeRTOS 7.3 (heap_2) and IAR EWARM. Linker mapping shows, that I am using almost 32k of RAM and does not allow me to add IP stack, since it takes 33k+ something of RAM altogether (definitely no limitations on code size, IAR is licensed). I’ve tried to relocate xHeap to AHB ram section and I got it compiling again. But as soon as I try to create task for IP stack handling - I get hardfault. Without it - eveything is ok.