Перейти до основного вмісту

Linker

Підтримувані родини STM32: G4 · H5 · H7 · L4 · U5

Цей компонент визначає розподіл пам'яті та розміщення сегментів для 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-код, щоб:

  1. Скопіювати ініціалізовані дані з Flash до RAM (секція .data)
  2. Обнулити секцію .bss
  3. Встановити початковий вказівник стека
  4. За потреби перемістити таблицю векторів до 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​

  1. Додайте Nvic_Lib до вашої CMake-бібліотеки.
  2. Підключіть Nvic_Port.h у вашому проєкті.
  3. Злінкуйте з файлами реалізації модуля Nvic.
  4. Налаштуйте модуль відповідно до вашого апаратного забезпечення.

Ліцензія​

Цей проєкт ліцензовано за Creative Commons Attribution–NonCommercial 4.0 International (CC BY-NC 4.0).

Ви вільні використовувати, змінювати та поширювати цю роботу в некомерційних цілях за умови належного зазначення авторства.

Повні умови дивіться у LICENSE.md або на creativecommons.org/licenses/by-nc/4.0.


Автори​

Внески вітаються! Будь ласка, відкрийте pull request.