eeucalyptus eeucalyptus - 1 year ago 68
C Question

Split section into multiple memory regions

I'm developing an application on an ARM Cortex-M microcontroller which has two RAM banks à 64kB. The first bank is directly followed by the second bank in the memory map.

The memory banks are currently split into two regions in my linker script. The first region contains the sections

. The second bank is used for
, which only take 1kB each (I'm using a different stack in FreeRTOS, which also manages it's own heap).

My problem is, that
is too large for the first bank. Therefore I'd like to move some of it's content to the second bank.

One way to accomplish this would be to create a new section, lets call it
, which is linked to the second bank. Single variables could then be added to this section using

The reasons why I am not using this solution are

  • I really want to maintain portability of my source code

  • There might be a whole lot of variables that would require this attribute and I don't want to choose the section for every single variable

Is there a better solution for this? I already thought of both memories as one region, but I don't know how to prevent the linker from misaligning the data across the boundary between both banks.

How can I solve my problem without using

Thank you!

Answer Source

For example you have 2 banks at 0x20000000 and 0x20010000. You wants use Bank2 for heap and (main) stack. I assume that you have large .bss because of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h. Now see heap sources in FreeRTOS/Source/portable/MemMang/. There are 5 implementations of pvPortMalloc() that do memory allocation.

Looks at lines in heap_X.c that you use

/* Allocate the memory for the heap. */
    /* The application writer has already defined the array used for the RTOS
    heap - probably so it can be placed in a special segment or address. */
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
    static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

So you can set configAPPLICATION_ALLOCATED_HEAP at 1 and say to you linker to place ucHeap at 0x20010000.

Another way is writing headers for each device that includes addresses of heap and stack and edit sources. For heap_1.c we can do next changes:

// somewhere in devconfig.h
#define HEAP_ADDR   0x20010000

// in heap_1.c
// remove code related ucHeap
// remove static uint8_t *pucAlignedHeap = NULL;
// and paste:
static uint8_t *pucAlignedHeap = (uint8_t *)HEAP_ADDR;

For heap_2.c and heap_4.c edit function prvHeapInit() as well.

Pay attention to heap_5.c that includes vPortDefineHeapRegions().

Now pvPortMalloc() will returns pointers to memory in Bank2. pvPortMalloc() used for allocations stacks of tasks, TCB and user varables. Read sources. Location of main stack depends of your device/architecture. For stm32 (ARM) see vector table or how to change MSP register.