cancel
Showing results for 
Search instead for 
Did you mean: 

Place constant at end of used flash - not specific address

LCE
Principal II

Heyho,

how can I put a constant at the end of the STM32's used flash? (using: STM32CubeIDE)

Not at a specific address (that's not a problem), but I'd like to have a constant always at the end of the used internal flash, independent of any other source code changes.

I just find that there's some ASCII characters = "ASCII" (twice) and lots of 0x00 at the end of my H7 and F7 bin files - that from my sources or placed by CubeIDE?

 

Thanks!

29 REPLIES 29
mfgkw
Senior

An alignment of 4 would be sufficient :)

*.map file will show you what was places after your section. 

I'm wondering why you do this?  

LCE
Principal II

I'm wondering why you do this?  

Part of file check for bootloader / application update

Radosław
Senior III

That i'm gessing, but still, not exacly understand why this method,

 

I'm juster after creating my bootleader for many decives  (end of flash was that last thing to bothering),   

LCE
Principal II

Paranoia! :D

LCE
Principal II

Shoot, now the STM32CubeProg complains about the *.elf file :

Warning: File corrupted. Two or more segments defines the same memory zone

And it doesn't load the complete flash content into the programmer.

:(

And this is very bad for first time flashing in production.

Showing your ld file could help helping ...

 

I tried a small project with this change in the ld file:

...

/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM

ENDOFFLASH :
{
. = ALIGN(8);
} >FLASH

/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

.ARM.attributes 0 : { *(.ARM.attributes) }
}

 

In the c file I added a variable like this:

const int __attribute__((section("ENDOFFLASH"))) lastVariable = 123;

ENDOFFLASH :
{

. = ALIGN(8);

*(ENDOFFLASH)

} >FLASH

 

Input section and output, don't mix this. Also used attribute for variable or keep for section should me used

LCE
Principal II

Now I moved the EOF section within the linker file right after the data init section where ">FLASH" is last used.

Then STM32CubeProg does not complain about the *.elf file, but the data window only shows the first flash section...

No problems with the bin file.

Here's part of my linker file - lots of sections... but it works! Except for the new EOF part with elf.

...

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* Specify the memory areas */
MEMORY
{
	ITCMRAM	(xrw)		: ORIGIN = 0x00000000, LENGTH = 64K		/* instruction RAM */

	FLBTVEC		(rx)	: ORIGIN = 0x08000000, LENGTH = 1K		/* bootloader vector table */
	FLBTFWINFO	(rx)	: ORIGIN = 0x08000400, LENGTH = 1K		/* bootloader firmware info */
	FLBOOT 		(rx)	: ORIGIN = 0x08000800, LENGTH = 250K	/* bootloader */

	FLUSER 	 	(rx)	: ORIGIN = 0x0803F000, LENGTH = 4K		/* TBD / shared One-Time-Programmable ROM */

	FLASHVEC 	(rx)	: ORIGIN = 0x08040000, LENGTH = 1K		/* application vector table */
	FLFWINFO 	(rx)	: ORIGIN = 0x08040400, LENGTH = 1K		/* application firmware info */
	FLASH  	 	(rx)	: ORIGIN = 0x08040800, LENGTH = 766K	/* application */

/* DTCM: 128 kB
 *	0x2000 0000 - 0x2001FFFF
 *	used as "general" RAM
 *	no DMA1/2 access, only MDMA memory to memory
 */
/*	DTCM_HPST(xrw)		: ORIGIN = 0x20000000, LENGTH = 15K		*/	/* DTCM heap & stack */
/*	DTCM_NOINIT(xrw)	: ORIGIN = 0x20003C00, LENGTH = 1K		*/	/* DTCM no init */
/*	DTCM_RAM(xrw)		: ORIGIN = 0x20004000, LENGTH = 112K	*/	/* DTCM */
	DTCM_RAM(xrw)		: ORIGIN = 0x20000000, LENGTH = 112K		/* DTCM */
	DTCM_NOINIT(xrw)	: ORIGIN = 0x2001C000, LENGTH = 1K			/* DTCM no init */
	DTCM_HPST(xrw)		: ORIGIN = 0x2001C400, LENGTH = 15K			/* DTCM heap & stack */

/*
without OCTOSPI / HyperRAM, all A2IP buffers in internal SRAM - NUCLEO debug only:
	SRAXI_D1(xrw)		: ORIGIN = 0x24000000, LENGTH = 96K
	SRAXI_D1_LWIP(xrw)	: ORIGIN = 0x24018000, LENGTH = 128K
	SRAXI_D1_A2IP(xrw)	: ORIGIN = 0x24038000, LENGTH = 96K
*/
/*
with OCTOSPI / HyperRAM, all A2IP buffers in external HyperRAM:
*/

/* internal */
	SRAXI_D1(xrw)		: ORIGIN = 0x24000000, LENGTH = 320K

	SRAM1_D2(xrw)		: ORIGIN = 0x30000000, LENGTH = 16K
	SRAM2_D2(xrw)		: ORIGIN = 0x30004000, LENGTH = 16K

	SRAM4_D3(xrw)		: ORIGIN = 0x38000000, LENGTH = 16K			/* only D3 access */

/* external via OCTOSPI / HyperRAM */
	OSPI_A2IP_D1(xrw)	: ORIGIN = 0x90000000, LENGTH = 0x0E00000	/* OCTOSPI 1 for A2IP */
	OSPI_FILE_D1(xrw)	: ORIGIN = 0x90E00000, LENGTH = 0x0200000	/* OCTOSPI 1 for file upload buffer */

/* external quad SPI flash via OCTOSPI */
	OSPI_FLASH(xrw)		: ORIGIN = 0x70000000, LENGTH = 0x0800000	/* OCTOSPI 2 for QSPI flash */
}


/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* Define output sections */
SECTIONS
{
	/* The startup code goes first into FLASHVEC */
	.isr_vector :
	{
		. = ALIGN(4);
		KEEP(*(.isr_vector))	/* Startup code */
		. = ALIGN(4);
	} >FLASHVEC

	/* 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 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


/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* FLASH sections for BOOTLOADER
 *	firmware version info
 */

	.FlashBootFwSection :
	{
		KEEP(*(.FlashBootFwSection)) ;
	} >FLBTFWINFO


/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* FLASH sections for APPLICATION
 *	user eeprom
 *	firmware version info
 */

	.FlashAppUserSection :
	{
		KEEP(*(.FlashAppUserSection)) ;
	} >FLUSER

	.FlashAppFwSection :
	{
		KEEP(*(.FlashAppFwSection)) ;
	} >FLFWINFO


/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* internal SRAM */

	/* used by the startup to initialize data */
	_sidata = LOADADDR(.data);

	/* 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 */
	} >SRAXI_D1 AT >FLASH
/* SRAXI_D1 or DTCM_RAM */

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* EOF string file info */
	.FlashAppEOF :
	{
		. = ALIGN(8);
		*(.FlashAppEOF)
		*(.FlashAppEOF*)
		. = ALIGN(8);
	} >FLASH
/* -------------------------------------------------------- */

	/* Uninitialized data section */

...
Radosław
Senior III

Maybe it is removed by linker as not used?

 

 One linker for APP and bootloader? Very bad idea !!!!!!!!!!!!