2021-08-16 03:29 PM
I am getting this error after I modify my linker script (which I got from a project created with CubeIde):
$arm-none-eabi-objcopy -O binary Prog_test_H735.elf Prog_test_H735.bin
$arm-none-eabi-size Prog_test_H735.elf
text data bss dec hex filename
35596 188 2108 37892 9404 Prog_test_H735.elf
$st-flash write Prog_test_H735.bin 0x8000000
st-flash 1.7.0
2021-08-16T15:18:11 INFO usb.c: Unable to match requested speed 1800 kHz, using 1000 kHz
2021-08-16T15:18:11 INFO common.c: H72x/H73x: 128 KiB SRAM, 1024 KiB flash in at least 128 KiB pages.
file Prog_test_H735.bin md5 checksum: 73e68311fa7a2f7533a11e4b1a1ca47, stlink checksum: 0x0039488a
2021-08-16T15:18:12 INFO common.c: Attempting to write 469762112 (0x1c000040) bytes to stm32 address: 134217728 (0x8000000)
2021-08-16T15:18:12 ERROR common.c: addr too high
stlink_fwrite_flash() == -1
make: *** [Makefile:130: flash] Error 255
Bellow follows the link script file. that I included the section ".d1_dma_buffer".
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7 series
** 1024Kbytes FLASH and 192Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2020 STMicroelectronics.
** All rights reserved.
**
** This software component is licensed by ST under BSD 3-Clause license,
** the "License"; You may not use this file except in compliance with the
** License. You may obtain a copy of the License at:
** opensource.org/licenses/BSD-3-Clause
**
****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 320K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_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) */
*(.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 */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Placing DMA data buffers at D1 region */
.d1_dma_buffer : /* Space before ':' is critical */
{
*(.d1_dma_buffer)
} >RAM_D1
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* 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;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
I have already read similar posts but none helped me understand how to fix this issue. It looks like it is a problem with my linker script construction. But I have used the same file in a CubeIde project that run with no problem.
Thank you for helping me understand the problem.
Regards,
E.
Solved! Go to Solution.
2021-08-16 03:56 PM
Have you created a ridiculously large .BIN file due to the sparse placement of data?
st-flash is probably choking on Prog_test_H735.bin
You can't place d1_dma_buffer in the middle of everything, this either needs to be a NOLOAD, or the data behind the RAM content needs to be staged in FLASH properly. You'd also need to fix your startup.s code to accommodate multiple RAM regions.
2021-08-16 03:56 PM
Have you created a ridiculously large .BIN file due to the sparse placement of data?
st-flash is probably choking on Prog_test_H735.bin
You can't place d1_dma_buffer in the middle of everything, this either needs to be a NOLOAD, or the data behind the RAM content needs to be staged in FLASH properly. You'd also need to fix your startup.s code to accommodate multiple RAM regions.
2021-08-16 04:08 PM
Thanks for your reply.
"Have you created a ridiculously large .BIN file due to the sparse placement of data?"
Yes, its generating a 470MB .bin file.
"You can't place d1_dma_buffer in the middle of everything, this either needs to be a NOLOAD, or the data behind the RAM content needs to be staged in FLASH properly. You'd also need to fix your startup.s code to accommodate multiple RAM regions."
It works at the CubeIde workflow.
As far as I understand, If I mark it as NOLOAD, I will be telling the section must not be loaded to memory. But I want that data there (at D1 region) so that DMA1 can have access to it.
2021-08-16 04:33 PM
A BIN file is raw data. It has no way to indicate where different sections should go.
You should mark those buffers as NOLOAD so they are not stored in the image file.
.d1_dma_buffer (NOLOAD) :
2021-08-16 04:50 PM
It worked. @TDK and @Community member were correct.
I still do not understand. How does the MCU knows which data belongs to which region if ..."A BIN file is raw data. It has no way to indicate where different sections should go.".
Thank you!
2021-08-16 04:59 PM
The linker script tells the MCU what data gets stored where.
The issue here is you're trying to initialize that data, so the ELF file has that data initialized in it. When it converts ELF to BIN, it creates a huge file because the "where" information is lost.
The solution in this case is to not initialize it. But if you did need to initialize it, you would tell the linker to store it into flash, and then you would need to write your program such that it gets transferred from flash to RAM_D1 on startup.
2021-08-16 06:05 PM
Here's where you choice of ST/GNU gets more complicated
You need to stage the initialization for the D1 RAM, in FLASH
>RAM_D1 AT> FLASH
This will give the content RAM_D1 addresses, but store them in FLASH at a point that extends beyond _sidata
You also need to establish the size of this data so during the startup code you can copy it from FLASH into the RAM_D1 space.You'll need to merge this with how the current code is working.
The ARDUINO/GNU guys seemed to have a more table driven approach to copying and zeroing memory. Keil has the loader construct a table which their scatter loader unpacks. They have been doing embedded compilers for a lot longer, so the solution is refined. They can also compress data when the net gains of space warrants it.
ELF and HEX files, are object files which contain metadata about address and length, this allows them to describe sparse and distinct areas of memory, without describing all the content in between,
2021-08-17 09:10 AM
Thank you for explaining the issue. Now I understand the consequences of my code. And yes, I do not need to initialize it. I just need to make sure that that vector will be placed at D1 region, where it can be accessed by DMA1.
2021-08-17 09:22 AM
Thank you for helping me understand all these minor but interesting aspects of the linker script. If I do not need to initialize, the "NOLOAD" still creates the section that I need to create memory structures that will go in RAM_D1?
Thank you for explaining the ELF and HEX files function. So as I understand, they will create the BIN according to what I need to be programmed at FLASH and my startup code will copy things at its expected place.
Regards.