Skip to main content
Intector
Senior
February 11, 2025
Question

compiler generating bad .elf file

  • February 11, 2025
  • 1 reply
  • 1655 views

Hello STM,

I noted that the compiler generated a bad .elf file using an STM32H7R3L8H6H MCU. I made a small demo project(attachment) that demonstrated the problem.

I'm using an external PSRAM with HEXASPI on XSPI1 port. I reserved a place on fixed addresses in the PSRAM where I placed my buffer.

This is the definition in the linker script:

/* ========================================================================= */
/* USER-PSRAM section definitions */
/* ========================================================================= */

 .user_psram_sec 0x90000000 :
 {
 /* ----- USER_PSRAM_MEM_01 - 10240 Bytes ----- */
 . = ABSOLUTE(0x90000000);
 *(.USER_PSRAM_MEM_01)

 /* ----- USER_PSRAM_MEM_02 - 40960 Bytes ----- */
 . = ABSOLUTE(0x90002800);
 *(.USER_PSRAM_MEM_02)

 /* ----- USER_PSRAM_MEM_03 - 10240 Bytes ----- */
 . = ABSOLUTE(0x9000C800);
 *(.USER_PSRAM_MEM_03)

 } >USER_PSRAM

 

This is the definition for the buffer in main.c:

static UCHAR user_psram_mem_01_buffer[USER_PSRAM_MEM_01_POOL_SIZE] __attribute__((section(".USER_PSRAM_MEM_01")));
static UCHAR user_psram_mem_02_buffer[USER_PSRAM_MEM_02_POOL_SIZE] __attribute__((section(".USER_PSRAM_MEM_02")));
static UCHAR user_psram_mem_03_buffer[USER_PSRAM_MEM_03_POOL_SIZE] __attribute__((section(".USER_PSRAM_MEM_03"))) ;

 

I can compile the program without error, but the download will fail. I tried using the STM32CubeProgrammer, but I got the same results.

Here is a screenshot from the download in the programmer:

Intector_0-1739248524203.png

 

I'm not 100% sure, but it looks like it ties to writing my byte buffer into the flash memory instead of 0x90000000.

The STM32H7RS series MCUs seem to be very powerful devices, but I'm beginning to understand why few people use them. It's simply not worth the hassle. Who in their right mind wants to become a volunteer bug-finder for STM? 

You know, Microsoft came up with a slogan once. It goes something like this:

"Knowledge shared is knowledge squared."

STM could introduce the "Bug Finder Badge."

 

OK, guys, keep hunting those bugs, and don't forget:

"Always be yourself unless you can be a pirate. Then always be a pirate."

 

1 reply

KnarfB
Super User
February 11, 2025

[Edited, my original attempt didn't survive a clean build]

Not sure what you see here. The .list file looks okay as it loads the 0x90000000 address in line 700003d4:

 

 

	 user_psram_mem_01_buffer[Idx01] = 0x00;
700003d4:	4a13 	ldr	r2, [pc, #76]	@ (70000424 <main+0x68>)
700003d6:	687b 	ldr	r3, [r7, #4]
700003d8:	4413 	add	r3, r2
700003da:	2200 	movs	r2, #0
700003dc:	701a 	strb	r2, [r3, #0]
...
70000424:	90000000 	.word	0x90000000
70000428:	90002800 	.word	0x90002800
7000042c:	9000c800 	.word	0x9000c800

 

 

writing my byte buffer

There is nothing to write here, it's data space.

And, it will not be initialized like normal global variables (in .data or .bss)

Did you have highest verbosity set in the above screendump?

hth

KnarfB

Intector
IntectorAuthor
Senior
February 11, 2025

Hey @KnarfB ,

Thank you for the fast answer.

This is my original mapping:

.user_psram_sec
 0x90000000 0xf000
 0x90000000 . = ABSOLUTE (0x90000000)
 *(.USER_PSRAM_MEM_01)
 .USER_PSRAM_MEM_01
 0x90000000 0x2800 ./Core/Src/main.o
 0x90002800 . = ABSOLUTE (0x90002800)
 *(.USER_PSRAM_MEM_02)
 .USER_PSRAM_MEM_02
 0x90002800 0xa000 ./Core/Src/main.o
 0x9000c800 . = ABSOLUTE (0x9000c800)
 *(.USER_PSRAM_MEM_03)
 .USER_PSRAM_MEM_03
 0x9000c800 0x2800 ./Core/Src/main.o

 

Here is the code of the for loop where write so that memory:

for(Idx01 = 0; Idx01 < 100; Idx01++){
 user_psram_mem_01_buffer[Idx01] = 0x00;
 user_psram_mem_02_buffer[Idx01] = Idx01;
 user_psram_mem_03_buffer[Idx01] = 150 - Idx01;
}

 

Here is the generated code for it:

 for(Idx01 = 0; Idx01 < 100; Idx01++){
700003ce:	2300 	movs	r3, #0
700003d0:	607b 	str	r3, [r7, #4]
700003d2:	e019 	b.n	70000408 <main+0x4c>
	 user_psram_mem_01_buffer[Idx01] = 0x00;
700003d4:	4a13 	ldr	r2, [pc, #76]	@ (70000424 <main+0x68>)
700003d6:	687b 	ldr	r3, [r7, #4]
700003d8:	4413 	add	r3, r2
700003da:	2200 	movs	r2, #0
700003dc:	701a 	strb	r2, [r3, #0]
	 user_psram_mem_02_buffer[Idx01] = Idx01;
700003de:	687b 	ldr	r3, [r7, #4]
700003e0:	b2d9 	uxtb	r1, r3
700003e2:	4a11 	ldr	r2, [pc, #68]	@ (70000428 <main+0x6c>)
700003e4:	687b 	ldr	r3, [r7, #4]
700003e6:	4413 	add	r3, r2
700003e8:	460a 	mov	r2, r1
700003ea:	701a 	strb	r2, [r3, #0]
	 user_psram_mem_03_buffer[Idx01] = 150 - Idx01;
700003ec:	687b 	ldr	r3, [r7, #4]
700003ee:	b2da 	uxtb	r2, r3
700003f0:	f06f 0369 	mvn.w	r3, #105	@ 0x69
700003f4:	1a9b 	subs	r3, r3, r2
700003f6:	b2d9 	uxtb	r1, r3
700003f8:	4a0c 	ldr	r2, [pc, #48]	@ (7000042c <main+0x70>)
700003fa:	687b 	ldr	r3, [r7, #4]
700003fc:	4413 	add	r3, r2
700003fe:	460a 	mov	r2, r1
70000400:	701a 	strb	r2, [r3, #0]
 for(Idx01 = 0; Idx01 < 100; Idx01++){
70000402:	687b 	ldr	r3, [r7, #4]
70000404:	3301 	adds	r3, #1
70000406:	607b 	str	r3, [r7, #4]
70000408:	687b 	ldr	r3, [r7, #4]
7000040a:	2b63 	cmp	r3, #99	@ 0x63
7000040c:	dde2 	ble.n	700003d4 <main+0x18>

 

The address values are stored at the end of the int main(void) function:

70000424:	90000000 	.word	0x90000000
70000428:	90002800 	.word	0x90002800
7000042c:	9000c800 	.word	0x9000c800

 

This looks OK, and nothing suspicious seems to be in that code. Still, for some reason, it is not possible to download it to the processor. You can use the STM32H7S78-DK to test the download. Regarding the memory, it's very similar to my board.

Look, @KnarfB, I've been on this planet since 1964 and have worked with several processors and compilers. My first processor was an Intel 8051, and it was a beauty. After I finished my time at the University, I had the pleasure of working with a team of brilliant people who developed a controller using a Motorola 68HC11. That chip just hit the market, and I learned a lot. The machine code at this time was not as complex as it is now, but still tricky. I'm surprised that the modern compiler still stores address values in lookup tables in some arbitrary memory areas.

However, one has to use the tools available. English isn't my native language, and things get bungled up sometimes. I'm trying to say that the STM32CubeProgrammer is trying to load the code into the FLASH address range and encounters an issue when attempting to write something to Segment[1] in this example. 

 

 

Stay vigilant and always remember:

"Always be yourself unless you can be a pirate. Then always be a pirate."

 

 

 

 

KnarfB
Super User
February 11, 2025

well, the first computer I had access to in the 70ies read the machine code from a punch tape and stored it on a magnetic drum...

Try the following:

 .user_psram_sec (NOLOAD) :
 {
 /* ----- USER_PSRAM_MEM_01 - 10240 Bytes ----- */
 . = ABSOLUTE(0x90000000);
 *(.USER_PSRAM_MEM_01)

 /* ----- USER_PSRAM_MEM_02 - 40960 Bytes ----- */
 . = ABSOLUTE(0x90002800);
 *(.USER_PSRAM_MEM_02)

 /* ----- USER_PSRAM_MEM_03 - 10240 Bytes ----- */
 . = ABSOLUTE(0x9000C800);
 *(.USER_PSRAM_MEM_03)

 } >USER_PSRAM

where NOLOAD indicates that the downloader should ignore it.

You may use the following command for .elf inspection:

arm-none-eabi-readelf -e C:\tmp\STM32H7R3L8H6H-Sandbox\STM32H7R3L8H6H-Sandbox\Appli\Debug\STM32H7R3L8H6H-Sandbox_Appli.elf

hth

KnarfB