2015-06-30 4 views
1

Я работаю над проектом, который включает в себя получение CMSIS-RTOS-упаковки FreeRTOS, работающей на STM32F051C6. Я пишу и отлаживаю код с VisualGDB внутри Visual Studio и генерирую код проекта с помощью инструмента STM32CubeMX, предоставляемого ST. RTOS работает невероятно хорошо, и я все улыбаюсь, однако я добавил очередь и пул памяти для обработки отправки и получения сообщений между задачами, а компилятор жаловался, что раздел памяти, который был скомпилирован/сгенерирован, не поместился бы в раздел памяти, указанный в компоновщике. Это было разрешено путем уменьшения размера кучи в заголовке конфигурации FreeRTOS.Определить границы памяти MCU MCU

Я немного недоволен тем, где это может меня принять, когда я хочу сделать проект более сложным (больше задач, очередей и т. Д.), Так как я могу начать еще больше уменьшать стек, чтобы разрешить раздел .bss ,

Так что мой вопрос - бы решение это будет расширить раздел .bss в раздел .data (раздел выше), чтобы получить дополнительную кучу и неинициализированными данных в разделе .bss? После некоторого осмотра и экспериментирования я обнаружил, что на самом деле используется только около 1% (если нет, меньше) раздела .data, согласно окну Memory Explorer VisualGDB во время сборки, и кажется сумасшедшим иметь всю эту неиспользуемую ОЗУ ,

В попытке сделать это сам я тщательно просмотрел сценарии компоновщика и код запуска, и я не мог найти, где определить начало и конец .bss. Можно ли определить эти границы, как я смогу сделать это, если это возможно? Если это невозможно, то как линкер знает, где эти границы находятся на целевом чипе?

Ниже то, что я думаю, соответствующие разделы в скрипте линкера:

.data : 
{ 
    . = ALIGN(4); 
    _sidata = .; 

    _sdata = _sidata; 

    PROVIDE(__data_start__ = _sdata); 
    *(.data) 
    *(.data*) 
    . = ALIGN(4); 
    _edata = .; 

    PROVIDE(__data_end__ = _edata); 
} > SRAM 

.bss : 
{ 
    . = ALIGN(4); 
    _sbss = .; 

    PROVIDE(__bss_start__ = _sbss); 
    *(.bss) 
    *(.bss*) 
    *(COMMON) 
    . = ALIGN(4); 
    _ebss = .; 

    PROVIDE(__bss_end__ = _ebss); 
} > SRAM 

PROVIDE(end = .); 

... и файл запуска:

extern void *_sidata, *_sdata, *_edata; 
extern void *_sbss, *_ebss; 

void __attribute__((naked, noreturn)) Reset_Handler() 
{ 
    //Normally the CPU should will setup the based on the value from the first entry in the vector table. 
    //If you encounter problems with accessing stack variables during initialization, ensure 
    //asm ("ldr sp, =_estack"); 

    void **pSource, **pDest; 
    for (pSource = &_sidata, pDest = &_sdata; pDest != &_edata; pSource++, pDest++) 
     *pDest = *pSource; 

    for (pDest = &_sbss; pDest != &_ebss; pDest++) 
     *pDest = 0; 

    SystemInit(); 
    __libc_init_array(); 
    main(); 
    for (;;) ; 
} 
+2

вы можете найти файл карты памяти? должен быть файл .map, который сообщает вам карту распределения памяти всех разделов в вашей двоичной директории. – user3528438

+0

Кажется, не может найти его и как его создать. Я использую arm-eabi-g ++ для ссылки – WoodyWoodsta

+1

Ваш компоновщик может сгенерировать его. –

ответ

0

Я думаю, что вы не можете установить размер .bss или .data раздел явно. Он определяется только вашей программой. Вы можете просмотреть, сколько памяти каждая переменная потребляет из файла карты.

Пример:

.bss.xHeap  0x0000000020000690  0xa000 obj/heap_2.o 

В моей установке FreeRTOS настроена

#define configTOTAL_HEAP_SIZE   ((size_t) (40 * 1024)) 

и я вижу все эти 40 КБ в моей карте-файл.

Linker знает, сколько памяти имеет ваш MCU, и пытается поместить на него все объекты памяти. Если он не подходит, вы видите ошибку.

Вы не можете «расширить» .bss в раздел .data, потому что первый занят неинициализированными статически распределенными переменными, а второй - инициализированными статически распределенными переменными. Если вы можете избавиться от некоторых статически распределенных переменных (например, глобальных), то размеры ваших .bss или/и .data уменьшатся. 8 КБ ОЗУ не очень много.

Возможно, вам стоит найти раздел (или подобное имя) в сценарии компоновщика и оптимизировать кучу (не путать с кучей FreeRTOS) и значения размера стека. Например. если вы используете только распределение памяти FreeRTOS, вы можете установить размер кучи как 0, и это позволит больше места для раздела .bss.

Из моего проекта:

_Min_Heap_Size = 0;  /* required amount of heap */ 
_Min_Stack_Size = 0x400; /* required amount of stack */ 

._user_heap_stack : 
{ 
    . = ALIGN(4); 
    PROVIDE (end = .); 
    PROVIDE (_end = .); 
    . = . + _Min_Heap_Size; 
    . = . + _Min_Stack_Size; 
    . = ALIGN(4); 
} >RAM 
+0

Отлично! Поэтому из того, что я собрал в вашем ответе, границы раздела «.bss» и «.data» на самом деле свободны для перемещения, как определено компоновщиком во время каждой сборки на основе неинициализированных и инициализированных данных, и вместе они ограничены вашими имеется общая оперативная память. Дает ваше предложение относительно кучи пользователя. Спасибо за вашу помощь! – WoodyWoodsta

+0

Добро пожаловать. Если быть точным, они ограничены размером раздела, где компоновщик должен их разместить. – LennyB