Crate linker_sections

Source
Expand description

Couple of macros for linker section memory initialization. This crate is designed for use on platforms with 32-bit aligned memory and 32-bit memory access, but was tested with cortex-m cores only.

This crate provides section memory initialization macro in a couple of following variants.

  • init_sections

    Use this macro if your section is defined using symbols

    • __s<section> for section VMA start,
    • __e<section> for section VMA end,
    • __si<section> for section LMA start.
    init_sections!(buffers, sram2, sram3);
  • init_sections_with_prefixes

    Use if you want to specify your section boundary symbols manually.

    init_sections_with_prefixes!(
        buffers(__s, __e, __si),
        sram2(__s, __e, __si),
        sram3(__s, __e, __si)
    );

§Example

Simple example defines a section .custom_data with start at 4-byte aligned __scustom_data and 4-byte aligned end at __ecustom_data. The initialization data goes at __sicustom_data.

MEMORY
{
    FLASH   : ORIGIN = 0x08000000, LENGTH = 32K
    RAM     : ORIGIN = 0x20000000, LENGTH = 16K
    DATA    : ORIGIN = 0x20004000, LENGTH = 16K
}

SECTIONS
{
    .custom_data : ALIGN(4)
    {
        . = ALIGN(4);
        __scustom_data = .;
        *(.custom_data .custom_data.*);

        . = ALIGN(4);
        __ecustom_data = .;
    } > DATA AT>FLASH

    __sicustom_data = LOADADDR(.custom_data);
} INSERT BEFORE .uninit;

In rust code it is needed to call macro init_sections with proper argument. the init_sections macro shall be usually called before or at the beginning of main function.

#![no_std]
#![no_main]

use linker_sections::init_sections;
use {defmt_rtt as _, panic_probe as _};

const INITIAL_VALUE: u32 = 0xDEAD_BEEF;

#[unsafe(link_section = ".custom_data")]
static mut STATIC_VARIABLE: u32 = INITIAL_VALUE;
#[cortex_m_rt::pre_init]
unsafe fn pre_init() {
    init_sections!(custom_data);
}

#[cortex_m_rt::entry]
fn main() -> ! {
    // print initialized variable value
    unsafe {
        defmt::info!("STATIC_VARIABLE = 0x{:08X}", STATIC_VARIABLE);
    }

    loop {}
}

§Safety

  • The symbols must be 4-byte aligned.
  • The symbols must point to memory with required access (read, write).
  • The symbols must represent continuos memory.

§Limitations

  • Each section’s name shall be a valid rust function name, but it does not have to be snake_case.
  • Only one macro can be called and it can be called at most once.

Macros§

init_sections
Defines pre-init function initializing linker section memory.
init_sections_with_prefixes
Defines pre-init function initializing linker section memory.