0

I'm debugging an embedded system with the stm32f746vg microcontroller where some speed critical sections of code are loaded in data RAM instead of flash. The rest of the non-critical code is loaded in flash, and the linker puts all of the .text sections in flash by default.

I do this relocation with nasty little function prototypes like this:

int main(void) __attribute__((section(".data")));

This forces main() to be loaded at address 0x2000 0000, which is what I want. Unfortunately, GDB expects main() to be loaded at address 0x0080 0000, where the rest of the program code is. As a result, GDB does not know where the line numbers for main() are. Is there any way to tell GDB "main() is actually at this address" ?

  • I DO have the newest version of arm-none-eabi-gdb and arm-none-eabi-gcc.
  • I am running arm-none-eabi-gcc with the -g option.
  • When I comment out the prototype for main that contains the __attribute__ directive, GDB has no problem finding line numbers.

Below is my linker script:

/* Entry Point */
ENTRY(Reset_Handler)


/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
/**
 * for the time being, we are going to buffer the image in sram1.  sram1 is
 * entirely dedicated to buffering images.
 * DTCM_RAM will be used for user variables
 */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
    DTCM_SRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 64K
/*    RAM1 (xrw)      : ORIGIN = 0x20010000, LENGTH = 240K*/
    RAM1 (xrw)      : ORIGIN = 0x20010000, LENGTH = 245760
    RAM2 (xrw)      : ORIGIN = 0x2004c000, LENGTH = 16K
    ITCM_SRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 16K
}

/* Define output sections */
SECTIONS
{
  /* Vectors need to be loaded at the start of flash. */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    /*KEEP (*(.init))*/
    /*KEEP (*(.fini))*/

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
    _exit = .;
  } >FLASH


   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
    .ARM : {
    __exidx_start = .;
      *(.ARM.exidx*)
      __exidx_end = .;
    } >FLASH


  /* used by the startup to initialize data */
  _sidata = .;

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data ORIGIN(DTCM_SRAM) :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } AT > FLASH
  __const_data_length__ = SIZEOF(.data);

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss . :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >DTCM_SRAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >DTCM_SRAM

  /* ram1 section, vars must be located here explicitly            */
  /* Example: extern int foo(void) __attribute__ ((section (".ram1"))); */
  /* No initialization is offered for this section.*/
  .ram1 ORIGIN(RAM1) :
  {
    *(.ram1)
  } >RAM1

  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

These are my gcc flags

CFLAGS  = -gstabs -Wall -std=gnu99 -ffunction-sections -Wno-unused-variable
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mlong-calls
CFLAGS += -I. -ggdb
CFLAGS += -DHSE_VALUE=$(HSE_VALUE)
CFLAGS += -DUSE_STDPERIPH_DRIVER
John M
  • 1,484
  • 1
  • 14
  • 27
  • 1
    `main` into `.data`? What is it supposed to achieve apart of running into troubles? – Eugene Sh. Oct 03 '16 at 16:10
  • @EugeneSh., apparently, it is supposed to achieve loading `main` into RAM instead of flash. I am inclined to suspect that there is a better way to accomplish this, but uncertain whether any such approach would solve the OP's problem. – John Bollinger Oct 03 '16 at 16:44
  • @JohnBollinger This is an awkward way indeed. I guess it's an XY-problem here.. – Eugene Sh. Oct 03 '16 at 16:45
  • If the problem is only with `main`, then make your `main` only call into another function that acts as the real `main`. – jxh Oct 03 '16 at 16:47
  • 2
    @jxh Still placing a function in `data` is a bada idea. Just place the function in a separate sub-`text` section, and direct it to RAM, if that's the intention. – Eugene Sh. Oct 03 '16 at 16:48
  • `(gdb) help section` – jxh Oct 03 '16 at 16:52
  • @EugeneSh. Regardless where the OP put it, this kind of problem would likely occur whenever `main` is not in `text`. – jxh Oct 03 '16 at 16:55
  • @EugeneSh. The microcontroller's RAM has much fewer wait states than flash. – John M Oct 03 '16 at 21:02

1 Answers1

1

You acheive this by placing main() in special code section of your choosing, call it .fast_exec

int main(void) __attribute__((section(".fast_exec")));

Then, in the linker script, place this new section to execute from RAM. It will be copied from FLASH at start-up:

.fast_exec : {
   *(.fast_exec)
} > DTCM_SRAM AT> FLASH

You can verify the effect of this, by checking the map file.

Refer to: https://stackoverflow.com/a/15142268/1096140

Community
  • 1
  • 1
hesham_EE
  • 1,125
  • 13
  • 24