2012-05-24 01:11 AM
Please, could you help me? with STM32F4xx.
But I think it's general problem with GNU linker.
I'm working on SW for colour graphical display application.
It works fine.
But I need to store some data to Flash after the program start.
I want allocate for this data all 16K Sector 1 in Flash area.
I have tried different ways but unsuccessfully.
My variable is
const unsigned
short
int
FlashArray[8192].
I have tried this:
const unsigned short
int
FlashArray[8192] __attribute__ ((at((uint32_t)0x08004000)));This doesn't work in GNU.
I have tried also this:
const
unsigned
short
int
FlashArray[8192]
__attribute__
((section(
''.flash_data_array''
)));
+
change in stm32_flash.ld:
/* Specify the memory areas */
MEMORY
{
FLASH0 (rx) : ORIGIN = 0x08000000, LENGTH = 16K
FLASH1 (rx) : ORIGIN = 0x08004000, LENGTH = 16K
FLASH2 (rx) : ORIGIN = 0x08008000, LENGTH = 992K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH0
/* My new eeprom area in FLASH */
.flash_data_array :
{
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >FLASH1
?
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.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 */
} >FLASH2
...
But this doesn't work too.
I don't know what's wrong.
I have tried to found out it on internet, but without success.
Here I found out this problem has more people.
Can you help me how to allocate variable array to Sector1 in Flash
and how to prohibit this sector to other flash data?
#linker2012-05-24 06:52 AM
No idea for GNU. However on IAR it works like this...
#pragma location=0xFF2002
__no_init const int beta;
2012-05-25 01:19 AM
const int myarray[mysize] __attribute__((section(''mysectionname''), used));
Note: used is important to say the linker to keep the variable (not to optimize it away) if there is no reference to it in the program.2012-05-27 11:53 PM
Hi,
I tried it, but it still doesn't work. When I look at map file after compiling, I can see allocated memory for new Flash sector ''.flash_data_array'', but there is no allocation for my flash variable FlashArray[].Also in debug mode (in Atollic studio) I can't see initialization values for this varaiable despite definition: const unsigned short int FlashArray[8192] __attribute__ ((section(''.flash_data_array''),used)) ={0x0000,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777,0x8888,0x9999,0xaaaa,0xbbbb,0xcccc,0xdddd,0xeeee}; It looks like linker doesn't assign flash variable to new created Flash sector, but there is no error alert after compiling.2012-05-28 03:45 AM
I found this:
I'm not sure if it is applicable for your problem,but this source, is a little pessimistic regarding your idea, it says: ''With the GNU GCC Compiler you may use only pointer definitions to access absolute memory locations.''2012-05-29 02:10 AM
> const unsigned short int FlashArray[8192]..
Either unsigned short or int but not both.2012-08-07 12:54 PM
I'm trying to do the same thing, reserve FLASH sector 1 for EEPROM emulation use, using the CodeBench Lite tools. Did you ever get this resolved/working?
Thanks in advance!2012-08-07 01:47 PM
Surely a pretty trivial linker script exercise?
.C usage__attribute__((__section__(''.eeprom''))) const short eeprom_junk[8192];
.LD used with Yagarto GNU/GCC 4.6.2
/*
Linker script for STM32F40x Chip Specific - sourcer32@gmail.com
*/
/* include the common STM32F40x sub-script */
INCLUDE ''STM32F4_COMMON.ld''
/* Memory Spaces Definitions */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
AUX (xrw) : ORIGIN = 0x2001C000, LENGTH = 16K
VECTOR (rx) : ORIGIN = 0x8000000, LENGTH = 16K
EEPROM (rx) : ORIGIN = 0x8004000, LENGTH = 16K
FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 1M-32K
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K /* also change _estack below */
}
/* highest address of the user mode stack */
_estack = 0x10010000;
/* Sections Definitions */
SECTIONS
{
/* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >VECTOR
.eeprom :
{
. = ALIGN(4);
*(.eeprom)
. = ALIGN(4);
} >EEPROM
/* the program code is stored in the .text section, which goes to Flash */
.text :
{
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_etext = .;
/* This is used by the startup in order to initialize the .data secion */
_sidata = _etext;
} >FLASH
/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >RAM
/* This is the uninitialized data section */
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* This is the user stack section
This is just to check that there is enough RAM left for the User mode stack
It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;
. = . + _Minimum_Stack_Size ;
. = ALIGN(4);
_eusrstack = . ;
} >CCM
__exidx_start = .;
__exidx_end = .;
/* after that it's only debugging information. */
/* remove the debugging information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
.MAP fragment, demonstrating placement
.isr_vector 0x08000000 0x188
0x08000000 . = ALIGN (0x4)
*(.isr_vector)
.isr_vector 0x08000000 0x188 out/startup_stm32f4xx.o
0x08000000 g_pfnVectors
0x08000188 . = ALIGN (0x4)
.eeprom 0x08004000 0x4000
0x08004000 . = ALIGN (0x4)
*(.eeprom)
.eeprom 0x08004000 0x4000 out/app.o
0x08004000 eeprom_junk
0x08008000 . = ALIGN (0x4)
.text 0x08008000 0x38f8
0x08008000 . = ALIGN (0x4)
Now personally, I'd be building the boot loader to live at 0x08000000, and the application at 0x08008000, but to each there own.
2012-08-07 02:00 PM
You could also back fill, space permitting, the VECTOR section
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text.SD*)
*(.text.*Handler)
} >VECTOR
2012-08-07 07:54 PM