cancel
Showing results for 
Search instead for 
Did you mean: 

Difficulties with Writing to the Flash of STM32L4R5

Shadow
Associate II

Hi,

I'm using an S-record file to update the MCU Firmware Application of STM32L4R5 through a Bootloader.

Most Row Addresses of the S-records in the file are at the 16-byte offset of a flash row (e.g. 0x08010010, 0x08010020, 0x08010030) but there are some at 8-byte and 12-bite offset, like this:

S3150808F7200000000000C0153F00000000DCCFD135FE

S30D0808F730E416F87F0100000049

S3090808F738E5010108C8

S3090808F73CC1010108E8

S3150808F74000000010002001000040100002004000E0

The Bootloader is writing to the 16-byte flash row as a Double Word at the order of receiving the S-records, padding the empty spaces with 0xFF to keep them not programmed.

In this case writing to the flash row at address 0x0808F730 takes place three times, like this:

0808F730 E416F87F01000000FFFFFFFFFFFFFFFF

0808F730 FFFFFFFFFFFFFFFFE5010108FFFFFFFF

0808F730 FFFFFFFFFFFFFFFFFFFFFFFFC1010108

However, address 0x0808F730 reads back as

0808F730 E416F87F01000000FFFFFFFFFFFFFFFF

As a result the Application doesn't start and enters the Error Handler instead.

I dumped the flash for both the operational application programmed with the debugger and this one programmed by the Bootloader. This row shows the only difference.

Does anybody know if a Flash row only accepts a single writing to a flash row?

How is this supposed to work, am I missing anything?

2 REPLIES 2
gbm
Lead III

Read the Flash description in the RefMan. Once you write the doubleword with anything other than all ones, you cannot update it (like write the second word).

The solution is to have a sliding 64-bit buffer and writing it to Flash when you receive (in S-record) the byte outside of the current buffer 64-bit block. Something like:

union {
    uint64_t dword;
    uint8_t byte[8];
} buffer;

uint32_t sliding_address;

if (sliding_address != (new_byte_address & ~7))
    Flash_write64(sliding address, buffer.dword);
sliding_address = new_byte_address & ~7;
buffer.byte[new_byte_address & 7] = new_byte;

Padding at a line level is a bad plan. The linker can split things up which are convenient for it, it is not aware of flash line widths. The input routines should instead fold multiple hex file lines.

Alternatively you can pre-process the hex file, and normalize it, so all the lines are consolidated and aligned to suit the target's architecture requirements / expectations.

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