Search code examples
clinkerembeddedstm32

Adding a RAM section in linker file STM32


I am trying very hard to understand how to use a linker file, but my brain is apparently not getting it at all. I am using an STM32L476, which has two RAM regions, RAM and RAM2 (memory definition below). I would like to put a buffer into RAM2, but there is no section for RAM2 in the default linker script that is generated by Cube. Seems like a good exercise for me. I really thought that the following would do the trick, where all I've added is the .sensor_buffer section:

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);    /* end of "RAM" Ram type memory */

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

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 96K
  RAM2    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 32K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 1024K
}

/* Sections */
SECTIONS
{
  .sensor_buffer :
  {
    KEEP(*(.sensor_buffer))
  } >RAM2
  
  /* The startup code into "RAM" Ram type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >RAM

  /* The program code and other data into "RAM" Ram type memory */
  .text :
  {
    ...
  } >RAM

  // Other Cube-generated sections here
}

However, this adds a .sensor_buffer section to an address that is not in RAM2. From the .map file:

...
.igot.plt       0x0000000020000190        0x0 load address 0x000000000800f29c
 .igot.plt      0x0000000020000190        0x0 c:/st/stm32cubeide_1.6.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_1.5.0.202011040924/tools/bin/../lib/gcc/arm-none-eabi/9.3.1/thumb/v7e-m+fp/hard/crtbegin.o

.sensor_buffer  0x0000000020000190     0x2000 load address 0x000000000800f29c
 .sensor_buffer
                0x0000000020000190     0x2000 Core/Src/main.o
                0x0000000020002190                . = ALIGN (0x4)

.bss            0x0000000020002190     0x1fb0 load address 0x000000000801129c
                0x0000000020002190                _sbss = .
                0x0000000020002190                __bss_start__ = _sbss
...

Can someone point out either where I went wrong here, and/or, even better, somewhere that I can work through some "easy" examples to get used to LD? I really want to get this stuff, but the first steps are really brutal for me without any resources except a rather dense set of man pages.

EDIT Adding the code used to declare the buffer. In main.c, global scope:

static uint8_t data[DATA_BUFFERS][DATA_SIZE] __attribute__((section(".sensor_buffer")));

Solution

  • You have an error somewhere else. Maybe you simply do not use this linker script (you forgot to add or change the name in the command line)

    I have compiled it and linked it without any problems with CubeIDE (I use 100 and 100 in the buffer declarations as I do not know the values of your macros [100x100 = 0x2710])

    .sensor_buffer  0x0000000010000000     0x2710
     *(.sensor_buffer)
     .sensor_buffer
                    0x0000000010000000     0x2710 Core/Src/main.o
    
    .isr_vector     0x0000000020000000        0x0
                    0x0000000020000000                . = ALIGN (0x4)