2024-08-26 03:23 AM - edited 2024-08-26 03:29 AM
Hi,
I want to flash my STM32L452RET6P using a .hex file. I am however struggling with the fact that STM IDE generates a .hex file with lines with only one WORD instead of the only supported double WORD when writing. So I need to buffer and assemble each double WORD from the .hex file. This involves a lot of tinkering for me, as in: how to buffer, how to know for sure we can finally write and so on. So is there any way to write only one WORD?
The HAL suggests it is possible as the write is done in two steps:
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
{
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
/* Set PG bit */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Program first word */
*(__IO uint32_t*)Address = (uint32_t)Data;
/* Barrier to ensure programming is performed in 2 steps, in right order
(independently of compiler optimization behavior) */
__ISB();
/* Program second word */
*(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
}
Another workaround could be to fix the .hex file formatting, so that each line in the .hex file is forced to contain a multiple of 8 bytes to be able to write straightaway to flash. I don't know why those weird 4 byte lines are in the file, it makes no sense to me.
Any suggestions?
My first thought was to write one word followed by 0xFFFFFFFF to be able to overwrite the second part if the .hex file contains any data for that part. But that wouldn't work if I'm right, because of how the ecc works.
Solved! Go to Solution.
2024-08-27 05:51 AM - edited 2024-08-27 05:53 AM
Hex file is generated by the GCC linker (LD), which isn't an ST product.
You can use alignment/padding within your linker file to enforce alignment to a 64-bit word and padding to a complete 64-bit word. The starting address for each linker section will always be 64-bit aligned if your sections start at the normal places. Don't begin your flash section at 0x08000001, for example.
> Unfortunately no, there are multiple. Take for example these lines, the address suddenly shifts with 4 bytes.
> :04 7220 00 9E467047 CF
> :10 7224 00 00000000000000000000000000000000 5A
But these are consecutive addresses. Should be able to buffer them and only write when the 64-bits are complete, or when the address has a gap.
2024-08-26 05:59 AM
You cannot write less than a double word to flash. This is a hardware limitation due to the presence of ECC bits for the flash.
(A double word is written by writing two consecutive words, but don't mistake this for the ability to write a single word independently.)
If the hex file is consecutive, which is likely, you should be able to write words as they appear in the hex file, and if the next word isn't present, write a buffer word to complete the double word.
2024-08-26 10:07 AM - edited 2024-08-26 10:11 AM
> You cannot write less than a double word to flash
I don't have a L4 but suspect that even the start address of the double word should be aligned on 8 bytes.
If only the last line of the hex file contains less than 8 bytes: in your .ld file add padding to 8 bytes at the end of flash data. Maybe, convert the hex to plain binary. Hex files are problematic: need parsing, can have holes and so on. Make it simple.
2024-08-26 11:22 PM
Thanks for your reply!
This explains clearly why the answer on my question is no.
About the hex file, does STM have strict guidelines how they generate them? I can use your solution to just consecutively write the hex file, but if for some reason it doesn't quite follow that guideline, I'm stuck again.
2024-08-26 11:39 PM
@Pavel A. wrote:I don't have a L4 but suspect that even the start address of the double word should be aligned on 8 bytes.
I can test that, but I suspect the same thing. Because ECC needs to be aligned somewhere.
@Pavel A. wrote:If only the last line of the hex file contains less than 8 bytes: in your .ld file add padding to 8 bytes at the end of flash data.
Unfortunately no, there are multiple. Take for example these lines, the address suddenly shifts with 4 bytes.
:04 7220 00 9E467047 CF
:10 7224 00 00000000000000000000000000000000 5A
Maybe, convert the hex to plain binary. Hex files are problematic: need parsing, can have holes and so on. Make it simple.
I actually started with a .bin file, but because of the checksum and addressing I switched to .hex files. A possibility is to let my host buffer and assemble correct frames which can be directly programmed. But I want to keep the host application as simple as possible as we need a smartphone to be able to flash the application. Do you have other suggestions for file formats? Or maybe a way to force the IDE to make 8 byte aligned .hex files?
2024-08-27 05:51 AM - edited 2024-08-27 05:53 AM
Hex file is generated by the GCC linker (LD), which isn't an ST product.
You can use alignment/padding within your linker file to enforce alignment to a 64-bit word and padding to a complete 64-bit word. The starting address for each linker section will always be 64-bit aligned if your sections start at the normal places. Don't begin your flash section at 0x08000001, for example.
> Unfortunately no, there are multiple. Take for example these lines, the address suddenly shifts with 4 bytes.
> :04 7220 00 9E467047 CF
> :10 7224 00 00000000000000000000000000000000 5A
But these are consecutive addresses. Should be able to buffer them and only write when the 64-bits are complete, or when the address has a gap.
2024-08-27 07:52 AM
> I actually started with a .bin file, but because of the checksum and addressing I switched to .hex files
Checksum? you can easily calculate checksum or crc of the bin file and verify on the board. A wrong move IMHO. Leads to self-inflicted pain.
2024-08-27 11:10 PM
I can easily generate a checksum, and with each line of the .hex file I send a crc32 along to ensure the data is correctly transferred. However, I also want to make sure the starting file is not corrupted to begin with. As we need high reliability for functional safety. A plain .bin file may have defects that we can't detect. At least, that's the thought behind the move. Other than the addressing.
2024-08-27 11:16 PM - edited 2024-08-27 11:29 PM
I will first give the 64-bit alignment a try. My address starts with 0802 0000 so no problems with that. This may be the best solution for my problem.
Edit: I don't think it's a GCC thing, as the .elf file is first generated, and then post processed to what you select. In my case .hex or .bin. But I'll look a bit around, maybe use my own .hex processor to generate the right files.
Yes, for now I only have consecutive addresses, but I'm afraid it may come with gaps in the future. We only have like 10% done of the real application, the first step was to build the bootloader.
2024-08-28 12:10 AM
I solved it by changing alignment in the linkerfile from 4 to 8, thanks for your help!!