cancel
Showing results for 
Search instead for 
Did you mean: 

I can't use function HAL_FLASH_Program to program same memory address twice

JimEno
Associate III

When I call function HAL_FLASH_Program twice with the same Flash address, the second call is ignored. See test code below.

int8_t buffer1[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

int8_t buffer2[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};

EraseIntFlash( 0x08200000, 0x08300000 );

HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, 0X0820000, buffer1);

HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, 0X0820000, buffer2);

 

In Memory Browser, I expect:

0x08200000   03020100 07060504 0B0A0908 0F0E0D0C

But I get:

0x08200000   03020100 07060504 FFFFFFFF FFFFFFFF

What is going on? I really need this to work. Can anyone provide insight or solution or workaround?

Jim Eno

1 ACCEPTED SOLUTION

Accepted Solutions

Tesla DeLorean,

A professional and technical response. Thank you.

I'll proceed with fixing issue on the IHex record decoding end (with a buffered receiver, etc.). Will look into improved solution as time and budget permit.

Thanks.

Jim Eno

View solution in original post

10 REPLIES 10

Right you get one shot per address.

The flash line contains unshown ECC bits

I think you need one larger, contiguous, buffer. Or the address needs to increase

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

Did you check for error codes/return values?

RM0456 Rev 3:

7.3.7 Flash main memory programming sequences
The Flash memory is programmed 137 bits at a time (128-bit data + 9 bits ECC).
Programming in a previously programmed address is not allowed except if the data to write
is full zero, and any attempt sets the PROGERR flag ...

hth

KnarfB

JimEno
Associate III

Tesla, Knarf,

Thanks for quick reply.

My actual task is to dynamically (run-time) load a 1 Mbyte data file into a reserved section of Flash using Intel Hex records from the serial port. I'm decoding the IHex records to a small 32 byte buffer and copying (attempting to) direct to Flash. Not really practical to reserve 1 MB RAM (not using a heap).

This scheme worked fine with my TI MSP432 micro. We are migrating to the STM family of micros. No, I did not thoroughly check the return values. I set a few breakpoints and got HAL_OKs.Surely there is a way to 'trick' the function into working. Can I pre-read the 16 byte block and edit ECC bits to make things look kosher? Can I disable ECC checking? Why does full zero work? I'm desperate!

Jim Eno

TDK
Super User

> Surely there is a way to 'trick' the function into working. Can I pre-read the 16 byte block and edit ECC bits to make things look kosher? Can I disable ECC checking? Why does full zero work?

No amount of software will get around the fundamental hardware limitations of the flash. You get one shot. STM32U5 allows a write of all 0 as a special case, which is why writing that works.

Some chips allow re-writing of flash (STM32F4 series, for example), but this one does not. It was a design choice to prevent unwanted/unexpected behavior.

You don't need to load the entire 1 MB at once. Write granularity is in 128 bit chunks. I recommended reading the flash section of the reference manual, particularly "7.3.7 Flash main memory programming sequences".TDK_0-1764887350352.png

 

If you feel a post has answered your question, please click "Accept as Solution".
JimEno
Associate III

TDK,

I attached a screenshot from STMCube.

It shows an Intel Hex file generated by the IDE. I used it to update my Application program. The result was a corrupted program. We typically used Intel Hex files with our basic BootLoader to update our code in the field. This won't work any more. What is the STM solution for updating code?

I don't mind the 16 byte block write, but preventing block re-writes with the ECC bits was a realy, realy, realy bad idea. What were you guys thinking?

Internal Flash Write issue.png

Jim Eno

> I don't mind the 16 byte block write, but preventing block re-writes with the ECC bits was a realy, realy, realy bad idea. What were you guys thinking?

Well, let's think about it objectively. For each flash page, the ECC bits are basically a hash of the data. Writing half the flash page will change the ECC bits to a basically random value. Writing the other half would change them to a different random value. But flash can only be written once. The ECC bits are in flash, part of the same flash they hold the ECC of, they're not some in some other NVRAM that can change at will. Can't change 0s to 1s.

It's not so much an idea or decision but a logical consequence of the fundamental hardware limitations of flash.

There are chips without ECC bits that let you write flash multiple times (STM32F4 series for one) if you don't want that behavior. ECC has benefits and drawbacks

 

The real issue here is the bootloader is not writing the entire flash page at once. That is a solveable problem and will fix the limitation you're running into. Preprocessing the HEX file could work, or doing some minimal processing in code to ensure a particular flash page is only written once.

If you feel a post has answered your question, please click "Accept as Solution".

You can normalize the .HEX file on the generation side, to ensure ordering, and FLASH line width.

You can buffer in RAM to ensure it meets the memory implementation goals. ie Folding multiple lines so you can write blocks of 16 or 128 bytes.

You can use binary forms, which is significantly more space efficient on the store medium, or transfer.

The FLASH design is about READING and EXECUTING efficiently, not really the ERASE/WRITE which are occurring a lot less frequently. The former allowing for nano-second operation, the latter micro or millisecond.

The width of the ECC is about efficacy, not user convenience, some of the STM32 designs this is 32-bit wide (36-bit, 32+4), others 64-bit (72-bit 64+8). 

The MCU want's larger fetches, the cache typically wanting 32-byte lines.

 

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

TDK and DeLorean,

Thanks for your responses.

1) I question the value of using ECC bits within the hardware at all. If you're trying to prevent writing to the same page twice then simply don't write to the same page twice. If the ECC bits are really needed for Reading/Execution (which I don't understand why) then I guess I could accept that. Enough on that topic.

2) We chose the STM32U5 because it's a really good micro (RAM, ROM, speed, power). The F4 won't do and a higher class micro would be overkill.

3) Preprocessing Hex file would be ugly. Maybe the Hex Gen Utility has a parameter that keeps addresses on 16 byte boundary and prevents splitting 16 byte memory blocks across two IHex records. I don't think there is. I could write code on the IHex decoding side to buffer record data into 16 byte chunks. This is NOT a trivial task. I would need a double buffer, read the Nth+1 IHex record before any Flash write decision and handle a lot of special cases.

4) Agree with you on binary format, but would have to re-write our Flash Programmer.

5) Intel Hex has been used for centuries to transfer code. Has no one else complained about this Flash write 'issue'? A general Forum question: How have you guys out there solved this problem?

Jim Eno

>>If the ECC bits are really needed for Reading/Execution (which I don't understand why) then I guess I could accept that.

It's used to FIX bit level errors in reading, allowing for higher speed operation, more robust memory operation, and lower cost (ie all memory cells work, less rejected die, higher yield).

The alternative is to have more FLASH memory, and a method to remap. They just choose to use ECC / hamming code type implementations, the array gets to be 7-8% larger, but the transistor/array geometry can likely be shrunk whilst maintaining reliability across the process window.

Exporting from the .ELF (binary object) might be easier than reprocessing the .HEX, but it's not an overwhelmingly difficult task, the format's been used since the 1970's, so not without documentation or examples. As long as the .HEX is linear the loader can use a spill/flash-line buffer.

I've built and posted ELF2HEX / ELF2DFU type tools with awareness of 8-byte alignment which has been necessary on some STM32 going back about a decade

https://community.st.com/t5/stm32-mcus-products/how-does-the-error-correction-code-ecc-for-flash-memory-work/td-p/101836

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