Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't write internal flash of same address twice

I'm trying to write to internal flash of STM32F1xxC (2KB per page), I can write to flash after a page erase, which converts every byte of that page to 0xFF.

It's very strange that I can not write the same address of flash twice, it is only possible when the previous value of that address is "0xFFFF".

What's the reason of this limitation? And also I was wondering why I can't write to odd addresses? (e.g. 0x803F0A1)

I don't think my question is platform (or vendor) specific, so I'm not adding any code.

I appreciate any help.

like image 283
Arman Avatar asked Mar 27 '16 05:03

Arman


2 Answers

It is in the nature of flash memory that write operations only allow transition of a bit from 1 to 0. To set a bit from 0 to 1 requires an erase operation and an erase operations applies to an entire erase block. The size of an erase block varies between devices.

In most flash implementations it is possible to modify a word that has already been written if the only bit changes are from 1 to 0. On the STM32F1xx however, even that is not possible, and since the word size is 16 bit, it is not possible to write a single byte if the other half of the word has been written.

The STM32F2xx (and also F4 and F7 ranges) partially solve this problem by allowing the flash to be written in 8, 16, and 32 bit modes, but it is still not possible to write a bit from 1 to zero when bits in the same word are already zero.

Another issue with STM32 on chip flash that you might need to be aware of is that during a write or erase operation, the bus stalls for a significant period. On traditioanl flash parts, you can read from one page while anither is being written, but on STM32 the whole flash memory is blocked. Since normally instruction fetch is from flash memory, this read-blocking means that during a flash erase/write operation no instructions are processed - the entire processor core is in a wait state (peripherals continue to run - unless using DMA reads from flash perhaps). For erase, the delay is page size dependent; on STM32F1xx this delay can be as much as 40ms, on F2 is 800ms! This makes on-chip flash write/erase operations problematic in real-time systems.

While flash memory in general imposes restrictions on write/erase operations, STs implementation imposes its own additional restrictions as described above. You always need to match your non-volatile memory technology to the application, or write your application to work with the non-volatile memory available. An external (off-chip) device may be appropriate in your case. Most technologies are some sort of compromise on speed, usability, endurance, density and cost in one way or another, but you could consider an external flash, EEPROM, FRAM or battery backed SRAM for example. If your processor lacks an external memory interface, or you cannot afford the necessary pin count to use an address bus accessed device, most technologies are available is serial-access devices through SPI or I2C for example.

Note also that the details of the STM32F1xx flash memory implementation are described in a separate document to the general user manual. Refer to PM0075 Programming manual - STM32F10xxx Flash memory microcontrollers

To be fair to ST, the restrictive STM32 flash implementation is not entirely arbitrary. The implementation no doubt requires less die space than a "full" implementation allowing space for more peripherals, larger memories or smaller die size (for reduced cost). Chip design involves many compromises, ST chose to compromise the flash flexibility for a large peripheral set it seems.

like image 71
Clifford Avatar answered Sep 29 '22 19:09

Clifford


It not very strange, but the rule with flash, because of the underlying technology (which I will not dare to explain, I'm not a physicist). Have a look here:

https://en.wikipedia.org/wiki/Flash_memory#Block_erasure

A location can, however, be rewritten as long as the new value's 0 bits are a superset of the over-written values. For example, a nibble value may be erased to 1111, then written as 1110. Successive writes to that nibble can change it to 1010, then 0010, and finally 0000. Essentially, erasure sets all bits to 1, and programming can only clear bits to 0.

As for:

And also I was wondering why I can't write to odd addresses?

This is a memory alignment limitation of your CPU - a very common one, don't blame it for that! A good explanation here:

https://stackoverflow.com/a/3025225/5257515

So, to write to an unaligned address, you'll have to write to the aligned address before it as well:

  • load the 16 (or 32 bits, depending on your alignment granularity limitation) bits memory aligned address value, which include the part you're interested in,

  • change this part leaving the rest untouched,

  • write back the new 16 (or 32) bits value to the memory aligned address.

EDIT:

For specific insight to STM32F1xx even more restrictive design, be sure to look at @Clifford comment.

like image 44
jbm Avatar answered Sep 29 '22 17:09

jbm