EmbDev.net

Forum: ARM programming with GCC/GNU tools how can i debug code in ram ?


von Max C. (maxchen)


Attached files:

Rate this post
useful
not useful
Hi,I try to debug my code in ram.but after searching on the web for a 
long time,I still can't figure it out.I use Sourcery G++ Lite Edition 
,openocd and  jlink on ubuntu 10.04.for the flash run,it work well.the 
MCU is STM32F103VE

I download the start up code and link script from the web.I modify the 
link script to something like this:

    .isr_vector :
    {
    . = ALIGN(4);
        KEEP(*(.isr_vector))            /* Startup code */
    . = ALIGN(4);
    } >RAM

    /* for some STRx devices, the beginning of the startup code is 
stored in the .flashtext section, which goes to FLASH */
    .flashtext :
    {
    . = ALIGN(4);
        *(.flashtext)            /* Startup code */
    . = ALIGN(4);
    } >RAM

    /* the program code is stored in the .text section, which goes to 
Flash */
    .text :
    {
      . = ALIGN(4);

        *(.text .text.* .gnu.linkonce.t.*)
      *(.plt)
      *(.gnu.warning)
      *(.glue_7t) *(.glue_7) *(.vfp11_veneer)

      *(.ARM.extab* .gnu.linkonce.armextab.*)
      *(.gcc_except_table)

    } >RAM

please help.

and sorry for my poor English.

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
So far I have not tested "RAM-debugging" with STM32 controllers so these 
are just some hints which might be helpful:

- In the Makefile there is a variable RUN_MODE which is set to FLASH_RUN 
in the file in the archiv. Set it to RAM_RUN. The stetting is later used 
to select the linker-script. Look into the output of make all and verify 
that the *_RAM linker-script is used. The content of RUN_MODE is also 
passed as a preprocessor definition so #ifdef RAM_RUN or #ifdef 
FLASH_RUN can be used in the source-code.

- SystemInit_ExtMemCtl() is called in the reset handler, usually 
SystemInit should do. Initialisation of the external memory interface 
can be enabled by a preprocessor define (see system_stm32*.c). Since 
initialization of the external memory interface can be enabled in 
SystemInit() it might be better to call SystemInit in the reset-handler. 
This may not cause a problem but it might be better to use the method 
intended by the STM library-developers until everything starts up as 
expected.

- I did not check every line in the linker-script for RAM but it looks 
o.k.

- Since the .data output-section is already at the correct location it 
is o.k. to wrap the first for-loop (copy data seg initializers...) with 
#ifdef FLASH_RUN/#endif

- MSP is already set in the reset-handler-function so there should be no 
need to add something for this.

- Since the interrupt-vector-table is also in RAM and not at the default 
location the the beginning of the flash-memory area the location has do 
be configured in SCB's VTOR register before any interrupt is enabled. 
See function NVIC_SetVectorTable in misc.c. Call could be done in the 
reset-handler.

- Since the core should start run the code in RAM, the 
debuggering-software should set the program-counter (PC) to the 
reset-handler's address. This can be done with OpenOCD just before a 
"resume".

von Max C. (maxchen)


Rate this post
useful
not useful
Thank you very much for you reply
I will try it later and report what I get.

Thanks again.

von Max C. (maxchen)


Rate this post
useful
not useful
Thank you Martin

By following you instruction ,I finaly made it work !

1.Modify the link script to put all the sections in ram

2.Set RUN_MODE to RAM_RUN in Makefile and make sure the linker link with 
the ram-run-link-script

3.Change the Reset_Handler to:
1
void Reset_Handler(void)
2
{
3
/* SCB's VTOR register to the correct interrupt-vector-table address in ram */
4
    #ifdef RAM_RUN
5
    NVIC_SetVectorTable(NVIC_VectTab_RAM,0X0);
6
    #endif
7
8
/* FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 
9
  required, then adjust the Register Addresses */
10
  SystemInit_ExtMemCtl();
11
12
  /* restore original stack pointer */
13
  asm(" LDR r0, =_estack");
14
  asm(" MSR msp, r0");
15
  
16
  /* Initialize data and bss */
17
   __Init_Data(); 
18
19
  /* Call the application's entry point.*/
20
  main();
21
}

4.Change __Init_Data to:
1
void __Init_Data(void)
2
{
3
  unsigned long *pulSrc, *pulDest;
4
5
  #ifdef FLASH_RUN
6
  /* Copy the data segment initializers from flash to SRAM */
7
  pulSrc = &_sidata;
8
9
  for(pulDest = &_sdata; pulDest < &_edata; )
10
  {
11
    *(pulDest++) = *(pulSrc++);
12
  }
13
  #endif
14
15
  /* Zero fill the bss segment. */
16
  for(pulDest = &_sbss; pulDest < &_ebss; )
17
  {
18
    *(pulDest++) = 0;
19
  }
20
}

5.Use the following openocd command:
1
reset
2
halt
3
load_image PATH_TO_IMAGE 0x0 TYPE_OF_IMAGE
4
reg pc 0x20000004
5
resume

von Angel Genchev (Guest)


Rate this post
useful
not useful
I did test with STM32F103C8T6 ($3 chinese board, known as blue pill).
The only thing I had to do is to write my linker script to put 
everything in RAM, then:
1. Put the jumpers at BOOT0 & BOOT1 pins to boot from RAM.
3. Debug via configured Eclipse+GDB+OpenOCD.
No code changes are necessary. The .elf contains all necessary sections 
so GDB is able to load the sections in RAM:
1
arm-none-eabi-gdb  /home/user/workspace/Project/build/main.elf
Then (in gdb) we connect to a running OpenOCD to load program into RAM:
1
target extended-remote 127.0.0.1:3333
2
monitor reset halt
3
load
The output from 'load' looks like:
1
Loading section .g_ISR_Vectors, size 0x130 lma 0x20000000
2
Loading section .text, size 0x1b34 lma 0x20000130
3
Loading section .data, size 0x18 lma 0x20001c64
4
Start address 0x200008ac, load size 7292
5
Transfer rate: 23 KB/sec, 1823 bytes/write.
You see that I defined vectors in separate section. Even the code for 
loading stack pointer is unnecessary (it saves 4 bytes of RAM in my case 
- for return address of reset handler), because my linker has the 
beginning of stack at end of the RAM which is by default after reset.
For eclipse there are no special settings - "load image" & "load 
symbols" are checked, everything works out of the box.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.