Linker
Цей компонент визначає розподіл пам'яті та розміщення сегментів для firmware мікроконтролерів STM32. Він є критично важливою частиною BSP (Board Support Package) і потрібен лінкеру, щоб правильно розмістити код і дані в пам'яті пристрою.
Призначення
Linker script забезпечує:
- Явний контроль над областями пам'яті, такими як Flash, RAM і CCMRAM
- Розміщення особливих секцій, зокрема таблиці векторів,
.text,.data,.bssі стека - Символи, на які посилається код під час запуску (наприклад,
_sdata,_edata,_sidata) - Підтримку масивів ініціалізації у стилі CMSIS (
.preinit_array,.init_array)
Ключові можливості
- Визначає
FLASH,RAMі, за потреби,CCMRAMз параметрамиORIGINтаLENGTH - Розміщує таблицю векторів на початку
FLASH - Резервує пам'ять для:
- Ініціалізованих даних (
.data) - Неініціалізованих даних (
.bss) - Купи (heap) і стека
- Ініціалізованих даних (
- За бажанням розміщує критичні дані або стек у
CCMRAMдля швидшого доступу - Додає дозволи лише для читання для
.init_array,.preinit_arrayі.fini_array, щоб уникнути попереджень лінкера про RWX
Типовий розподіл
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
}
SECTIONS
{
.isr_vector :
{
KEEP(*(.isr_vector))
} > FLASH
.text :
{
*(.text*)
*(.rodata*)
} > FLASH
.data : AT (_etext)
{
_sdata = .;
*(.data*)
_edata = .;
} > RAM
.bss :
{
_sbss = .;
*(.bss*)
_ebss = .;
} > RAM
.ccm_data :
{
*(.ccmram*)
} > CCMRAM
.stack :
{
. = ALIGN(8);
_stack_top = .;
} > RAM
/* Initialization arrays */
.preinit_array (READONLY) :
{
KEEP(*(.preinit_array))
} > FLASH
.init_array (READONLY) :
{
KEEP(*(.init_array))
} > FLASH
}
Надані символи
Linker script визначає символи, що використовуються в процесі запуску та ініціалізації:
-
_sidata: початкова адреса початкових значень секції.data, зазвичай розташована у Flash -
_sdata: початкова адреса секції.dataв RAM -
_edata: кінцева адреса секції.dataв RAM -
_sbss: початкова адреса секції.bss(неініціалізовані дані) в RAM -
_ebss: кінцева адреса секції.bssв RAM -
_ccmram_start,_ccmram_end: межі області пам'яті CCMRAM (необов'язково) -
_stack_top: вершина стека, зазвичай у кінці RAM
Ці символи використовує startup-код, щоб:
- Скопіювати ініціалізовані дані з Flash до RAM (секція
.data) - Обнулити секцію
.bss - Встановити початковий вказівник стека
- За потреби перемістити таблицю векторів до RAM або CCMRAM
Примітки щодо використання
- Linker script має бути синхронізований з конфігурацією пам'яті, визначеною в налаштуваннях вашого проєкту.
- Усі власні секції, додані у вашому коді (наприклад,
.ccmram,.bootloader,.shared), необхідно врахувати в linker script. - Звертайте увагу на вирівнювання та дозволи секцій, щоб уникнути hard fault або неочікуваної поведінки.
Інтеграція
Файл linker script генерується CMake з STM32G4xx_Linker.ld.in і залежить від налаштованого MCU STM32.
Переконайтеся, що прапорці вашого компілятора і лінкера дозволяють використовувати ці символи у коді на C, зазвичай так:
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sidata;
extern uint32_t _sbss;
extern uint32_t _ebss;
extern uint32_t _ccmram_start;
extern uint32_t _ccmram_length;
extern uint32_t _ccmram_end;
extern uint32_t _ram_start;
extern uint32_t _ram_length;
extern uint32_t _ram_end;
🛠 Інтеграція з CMake
- Додайте
Nvic_Libдо вашої CMake-бібліотеки. - Підключіть
Nvic_Port.hу вашому проєкті. - Злінкуйте з файлами реалізації модуля Nvic.
- Налаштуйте модуль відповідно до вашого апаратного забезпечення.
Ліцензія
Цей проєкт ліцензовано за Creative Commons Attribution–NonCommercial 4.0 International (CC BY-NC 4.0).
Ви вільні використовувати, змінювати та поширювати цю роботу в некомерційних цілях за умови належного зазначення авторства.
Повні умови дивіться у LICENSE.md або на creativecommons.org/licenses/by-nc/4.0.
Автори
- Mr.Nobody — embedbits.com
Внески вітаються! Будь ласка, відкрийте pull request.