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.
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".
Thank you very much for you reply I will try it later and report what I get. Thanks again.
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 |
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
Log in with Google account
No account? Register here.