cancel
Showing results for 
Search instead for 
Did you mean: 

How to load code directly in RAM using ST-Link and STM32CubeIDE?

TPope.1
Associate II
1 ACCEPTED SOLUTION

Accepted Solutions
TPope.1
Associate II

Ok, so the problem was that SCB->VTOR was not correctly set (even before HAL_Init() it still pointed to the beginning of FLASH - 0x0800...)

After HAL_Init() I've set

SCB->VTOR = (uint32_t)(0x24040000);

and SysTick interrupt works fine now.

Edit:

Ok, so a better implementation imo is to have in *FLASH.ld:

_eflash = ORIGIN(FLASH);

And in *.c something like:

extern uint32_t _eflash;

SCB->VTOR = (uint32_t)(_eflash);

View solution in original post

8 REPLIES 8
TPope.1
Associate II

I have a H743ZI2 nucleo board.

I've tried placing the FLASH section in RAM:

RAM_D1 (xrw)  : ORIGIN = 0x24000000, LENGTH = 512K

split in smth like:

RAM_D1 (xrw)  : ORIGIN = 0x24000000, LENGTH = 256K

FLASH (xrw) : ORIGIN = 0x2A000000, LENGTH = 256K

or splitting RAM and placing sections which were previously in FLASH as:

.isr_vector :

 {

   . = ALIGN(4);

   KEEP(*(.isr_vector)) /* Startup code */

   . = ALIGN(4);

 } >SOME_NEW_RAM_REGION

either way it doesn't work (both ST-LINK GDB sv and OpenOCD).

Now, I know there is a previous q, essentially the same, but can someone please provide a detailed and steps to achieve this?

Thank you.

Error for OpenOCD:

Error: Failed to write memory at 0x2a000200

Error: Failed to write memory at 0x2a001898

MM..1
Chief III

You need better calculator 0x24000000 + 256k = 0x24040000

Ok, so in FLASH.ld:

MEMORY

{

 /*FLASH (rx)    : ORIGIN = 0x08000000, LENGTH = 2048K*/

 DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

 RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 256K

 FLASH (xrw) : ORIGIN = 0x24040000, LENGTH = 256K

 RAM_D2 (xrw)  : ORIGIN = 0x30000000, LENGTH = 288K

 RAM_D3 (xrw)  : ORIGIN = 0x38000000, LENGTH = 64K

 ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K

}

and RAM.ld:

MEMORY

{

 RAM_EXEC (xrw) : ORIGIN = 0x24000000, LENGTH = 256K

 DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K

 RAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288K

 RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K

 ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K

}

I've tried setting breakpoints to void FLASH_IRQHandler(void), and further in other function pointers, execution does not break,

but flags are set in IRQ Handler, because execution is dependent on those flags and it behaves as expected.

Execution does not terminate cleanly, last stack state is:

Thread #1 [main] 1 [core: 0] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)   

   0x8000b32   

   <signal handler called>() at 0xfffffff9   

   0x0   

   flash_runnable() at TestFlash.c:127 0x240406aa   

0x8000b32, is an address in flash region of uc.

Did I miss something, like relocating some mem regions, maybe vtor or?

ssipa.1
Associate II

I've read that post, at least for me, instructions are vague.

However, this is output from readelf cmd, suggested to be used in that post:

readelf -S Bootloader.elf

There are 23 section headers, starting at offset 0x1d9744:

Section Headers:

 [Nr] Name             Type           Addr    Off   Size  ES Flg Lk Inf Al

 [ 0]                  NULL           00000000 000000 000000 00     0  0 0

 [ 1] .isr_vector      PROGBITS       24040000 010000 000298 00  A 0  0 1

 [ 2] .text            PROGBITS       24040298 010298 0050c0 00 AX 0  0 4

 [ 3] .rodata          PROGBITS       24045358 015358 000038 00  A 0  0 4

 [ 4] .ARM             ARM_EXIDX      24045390 015390 000008 00 AL 2  0 4

 [ 5] .init_array      INIT_ARRAY     24045398 015398 000004 04 WA 0  0 4

 [ 6] .fini_array      FINI_ARRAY     2404539c 01539c 000004 04 WA 0  0 4

 [ 7] .data            PROGBITS       24000000 020000 000014 00 WA 0  0 4

 [ 8] .bss             NOBITS         24000014 020014 000118 00 WA 0  0 4

 [ 9] ._user_heap_stack NOBITS         2400012c 02012c 000604 00 WA 0  0 1

 [10] .ARM.attributes  ARM_ATTRIBUTES 00000000 020014 00002e 00     0  0 1

 [11] .debug_info      PROGBITS       00000000 020042 017bac 00     0  0 1

 [12] .debug_abbrev    PROGBITS       00000000 037bee 002b3e 00     0  0 1

 [13] .debug_aranges   PROGBITS       00000000 03a730 000ba8 00     0  0 8

 [14] .debug_ranges    PROGBITS       00000000 03b2d8 000ae0 00     0  0 8

 [15] .debug_macro     PROGBITS       00000000 03bdb8 035502 00     0  0 1

 [16] .debug_line      PROGBITS       00000000 0712ba 00e0e9 00     0  0 1

 [17] .debug_str       PROGBITS       00000000 07f3a3 153d00 01 MS 0  0 1

 [18] .comment         PROGBITS       00000000 1d30a3 000053 01 MS 0  0 1

 [19] .debug_frame     PROGBITS       00000000 1d30f8 002f1c 00     0  0 4

 [20] .symtab          SYMTAB         00000000 1d6014 002070 10    21 291 4

 [21] .strtab          STRTAB         00000000 1d8084 0015cd 00     0  0 1

 [22] .shstrtab        STRTAB         00000000 1d9651 0000f0 00     0  0 1

TPope.1
Associate II

Ok, so the problem was that SCB->VTOR was not correctly set (even before HAL_Init() it still pointed to the beginning of FLASH - 0x0800...)

After HAL_Init() I've set

SCB->VTOR = (uint32_t)(0x24040000);

and SysTick interrupt works fine now.

Edit:

Ok, so a better implementation imo is to have in *FLASH.ld:

_eflash = ORIGIN(FLASH);

And in *.c something like:

extern uint32_t _eflash;

SCB->VTOR = (uint32_t)(_eflash);

MM..1
Chief III

Maybe when you read better system c file you see here lines

/*!< Uncomment the following line if you need to relocate your vector Table in
     Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field. 
                                   This value must be a multiple of 0x200. */

And entered valid values setup all in build for you...