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
8
  • 1
    main into .data? What is it supposed to achieve apart of running into troubles? Commented Oct 3, 2016 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. Commented Oct 3, 2016 at 16:44
  • @JohnBollinger This is an awkward way indeed. I guess it's an XY-problem here.. Commented Oct 3, 2016 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. Commented Oct 3, 2016 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. Commented Oct 3, 2016 at 16:48

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

That's essentially what I'm doing now. Is ".fast_exec" a special name that GDB recognizes?
No, it's not any special.
Could you provide what gdb says when you type info symbol main and info address main?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.