2024-02-28 08:38 AM
Hello, I'm new in STM32CubeIDE.
I want to define global variables with initial values in different RAM regions (e.g., RAM_D1, RAM_D2) using STM32CubeIDE for STM32H743.
In Keil, I can usually achieve this by modifying the SCT file as shown in the diagram below.
However, simply adding a section in the LD file does not ensure that variables will have initial values.
So how can I, like in Keil, achieve the definition of global variables with initial values in different RAM regions of STM32H743 using a simple method such as __attribute__ in the code or any other straightforward approach?
Anyone can help me?
By the way, I'm not a native English speaker, so I apologize for any mistakes in my expression
Many thanks,
Florenc_Rain
2024-02-28 03:12 PM - edited 2024-02-28 03:17 PM
The most simple and quick way, with least headache, is to rewrite your static initializers to runtime code.
Otherwise you need to fumble with asm code or something even more terrible in C. Just write something like:
__attribute_((section(".RAM_D1")) uint32_t AXISRAMBUF[10];
__attribute_((section(".RAM_D1")) uint16_t AXISRAMCount;
.......
void init()
{
extern char start_RAM_D1[], char end_RAM_D1[];
memset(start_RAM_D1, 0, end_RAM_D1 - start_RAM_D1); // Zero fill
AXISRAMCount = 1; // initialize data
...............
}
Do this for all non-default memory areas. (the default area is where the compiler and linker place the data and bss, and it will be initialized normally).
Exported symbols for start_RAM_D1, end_RAM_D1 etc. should be defined in the link script (.ld) , around the corresponding memory areas.
Of course it is nice when the compiler & linker do this work for you, that's why Keil MDK costs money ))
2024-02-28 03:28 PM
Keil's linker builds a table and __scatterload acts on it as part of the code in __main before it calls your main() function.
With GNU/GCC the linker script has symbols and directives, to mark beginning and end, and code you add into startup.s acts on it. Team ST is lazy, Team Arduino automated it with tables too.
You want it to copy and zero memory in RAM, add code to startup.s, or rewrite it.
2024-02-29 04:02 AM
Thank you for your response. I believe I have found a solution. I have defined RW-data in the RAM_D1 region using the following method.
1:Add the RAM_D1 section in the LD file.
/* used by the startup to initialize data */
_siram_d1_data = LOADADDR(.ram_d1_data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.ram_d1_data :
{
. = ALIGN(4);
_sram_d1 = .; /* create a global symbol at ram_d1 start */
*(.ram_d1_data)
*(.ram_d1_data*)
. = ALIGN(4);
_eram_d1 = .; /* create a global symbol at ram_d1 end */
} >RAM_D1 AT> FLASH
2:Add the following assembly code in the startup file.
ldr r0, =_sram_d1
ldr r1, =_eram_d1
ldr r2, =_siram_d1_data
movs r3, #0
b LoopCopyRAMD1DataInit
CopyRAMD1DataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyRAMD1DataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyRAMD1DataInit
2024-02-29 04:04 AM
Thank you for your response. I believe I have found a solution. I have implemented the definition of RW-data in the RAM_D1 region using the method mentioned above.