Showing results for 
Search instead for 
Did you mean: 

Hex file details and start address for bootloading my code over I2C

Associate II

I have a complex system comprised of one STM32G474RE that serves as a USB to I2C bridge. The G4 communicates with about a dozen STM32G051F8 chips over I2C. I designed the board with the ability to independently control the BOOT pin of each G0 so I can boot a single device into the system memory and utilize the built in I2C bootloader. I've read AN2606 and AN4221 and understand how to send data to the G0.

I am currently stuck trying to understand what bytes to pull out of the output file (currently I've generated .bin, .hex and .elf files from STM32CubeIDE). I also do not know what the starting address for the data should be. This is a STM32CubeIDE standard project, I've only modified "main.c" so you can assume default addresses. I would also like to know if there are size limitations for writing flash. I know the I2C protocol in AN4221 says I can write a max of 256 bytes at a time but I am trying to understand if there is a minimum amount that must be written to in flash at a time.

I've read the documents pretty thoroughly, but just can't find details on what to do with the output files and where to start writing the data. I appreciate any pointers you can give.




Intel/Motorola HEX files have existed since the late 1970's I'd expect there to be some documentation for the formats. They describe content in memory, and provide the address. The .HEX will likely be about 2.5x larger than the binary data it describes.

The base address for FLASH in STM32 is typically 0x08000000, your basis should be obvious from the linker script, or can be seen in the .ELF file, perhaps inspect via objcopy or objdump. Or look at the .MAP files.

A line in the .HEX will typically describe 16 or 32 bytes.

The width of the FLASH lines in your given STM32 should give you insight into minimum write size and alignment.

I'd say write as much as possible, and alignment on 8-byte / 64-bit should be universally viable across all the STM32 families.

Writing bytes being the least efficient, and most prone to issues, especially with wider FLASH lines and ECC

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Associate II

A bit of background, I am a test engineer whose primary focus for the past 20+ years has been automating test equipment measurements on the PC. I've just started with MCU's and am using ST as STM32CubeIDE allows me to be successful without any knowledge of "linker script" that you mentioned. I have read up on the different file formats but I am not seeing where they correspond to address in flash. I did find the memory map in the reference manual that gave 0x0800_8000 as the start of flash but had no idea if my code should reside there or if it is offset by some amount. Can you explain where the linker script is and how to read it? Is there a way to figure out what part of these binary files actually gets sent to the DUT without connecting my I2C sniffer and logging a bootload from STM32CubeProgrammer?

All the .BIN would get sent, the basis would depend on the linker script, it is not inferred in the binary. The .ELF would describe the sections, per the script, the format is well documented, the data in the (BITS) sections going to the target device. The sundry debugging, symbols and metadata would not.

Can't say I've use I2C via STM32 Cube Programmer. Is that via the ST-LINK/V3SET or Aardvark probes?

The COM/UART protocol is described in AN3155, there's an example of an Arduino implementation of the firmware update mechanics in the MKR WAN1300 repository.

AN4221 for I2C, suspect the mechanics here being very similar to the UART

There are several threads on the forum too.


Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Associate II

I think there was a video series from ST showing how to bootload over I2C. I think it uses the Bridge I2C connections to connect. Simply click the drop down and select I2C and it will use the Bridge SCL and SDA on the ST Link V3SET and V3MODS. I'm still waiting to get my board back from assembly to try it but I've got my Saleae ( logic analyzer ready to go, I hope to record CubeProg sending the file and reverse engineer that to understand the actual writing. If I'm ever successful, I'll try to do a write up for other newbies like myself to follow.



Here's a screenshot of my linker script, is this what I'm looking for as the definition of the start of my user code:




Ok, so 0x08000000, the base of FLASH in these parts. Could be deep in like 0x08008000 (+32KB) if you had your own loader that's more aware of your board's hardware.

The AN4221 should be an adequate document to code from.

If you have a device and can interact with it, should just be able to code I2C interactions and then relate to the App Note, if you're an experiential learner.

Yes you could use the logic analyzer to confirm aspects of the App Note, but I don't really think that's necessary.

The I2C address it responds too should be covered by AN2606. Watch that also for pins where you don't want noise from, as those will be determined to be connection attempts prior to you I2C activity.

You could use a NUCLEO or similar break-out as a proxy if built hardware is weeks away.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..