Цитата(vanek18 @ Apr 14 2015, 12:48)

А вот про менеджер памяти можно поподробнее? Я всегда память распределял стандартными средствами keil.
Брал в этой
теме.
Остаток памяти для первого банка берется из переменных в скрипте линковщика (пример для lpc1754):
CODE
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
/*INCLUDE "memory.ld"*/
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00004000
ram1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x00004000
}
_eram = 0x10000000 + 0x00004000;
/* Section Definitions */
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
KEEP(*(.hware))
KEEP(*(.offset))
KEEP(*(.templ))
KEEP(*(.swvers1))
KEEP(*(.swvers2))
KEEP(*(.swvers3))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > rom
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
__exidx_end = .;
. = ALIGN(4);
_etext = .;
_sidata = .;
.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
_sbss = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > ram
/* heap section */
.heap (COPY):
{
__Heap_Start = .;
_end = __Heap_Start;
end = __Heap_Start;
*(.heap*)
__Heap_End = .;
} > ram
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > ram
/* Set stack top to end of ram , and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(ram ) + LENGTH(ram );
__StackLimit = __StackTop - SIZEOF(.co_stack);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds ram limit */
ASSERT(__StackLimit >= __Heap_End, "region ram overflowed with stack")
.data_dma (COPY): ALIGN(4)
{
__data_dma_start = .;
KEEP(*(.dma_vars))
} > ram1
. = ALIGN(4);
__data_dma_finish = .;
}
а дальше:
Код
#define SECOND_BANK_END (0x2007FFFFUL)
void init_system_heap(void) {
extern unsigned long __Heap_Start;
extern unsigned long __Heap_End;
extern unsigned long __data_dma_finish;
system_heap.start = (heap_mcb *) (&__Heap_Start);
system_heap.freem = (heap_mcb *) (&__Heap_Start);
system_heap.hsize = (unsigned long) (&__Heap_End) - (unsigned long) (&__Heap_Start) + (unsigned long) 1;
heapinit(&system_heap);
heapadd(&system_heap, (heap_mcb *) (&__data_dma_finish), (unsigned long) SECOND_BANK_END - (unsigned long) (&__data_dma_finish));
}
второй банк добавляю соответственно после памяти выделенной для DMA буферов (__data_dma_finish) и до конца второго банка. Для себя добавлял еще обертки для freeRTOS. Только сейчас понял что SECOND_BANK_END можно считать из ram1_ORIGIN+ram1_LENGTH.
Секция .co_stack соответственно используются для стека - т.к. я использую rtos то этот стек используется насколько я понимаю только функцией main до старта шедулера и в обработчиках прерываний).
Код из startup_LPC17xx.c:
Код
#define STACK_SIZE 0x00000100 /*!< The Stack size suggest using even number */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];
......
__attribute__ ((used,section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
/*----------Core Exceptions------------------------------------------------ */
(void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer */
Reset_Handler, /*!< Reset Handler */
NMI_Handler, /*!< NMI Handler */
HardFault_Handler, /*!< Hard Fault Handler */
MemManage_Handler, /*!< MPU Fault Handler */
BusFault_Handler, /*!< Bus Fault Handler */
UsageFault_Handler, /*!< Usage Fault Handler */
0,0,0,0, /*!< Reserved */
SVC_Handler, /*!< SVCall Handler */
DebugMon_Handler, /*!< Debug Monitor Handler */
0, /*!< Reserved */
PendSV_Handler, /*!< PendSV Handler */
SysTick_Handler, /*!< SysTick Handler */
....