EEPROM/FLASHROM の書き込み回数が保証回数を超えた場合の挙動 

#目的
EEPROM/FLASHROM を制御するマイコン側のエラー処理設計を行うため
書き込み保証回数を超えた書き込みを行った場合、どのようなエラーが発生するか検証した。

#検証したEEPROM/FlashROM一覧
||メーカ||Type|Size|IF|Manual|
|---|---|---|-------|-------|---|---|
1|ROHM|BR93L46|EEPROM|1Kbit(128byte)|SPI *1|[Link](https://www.rohm.co.jp/datasheet/BR93L56RF-W/br93lxx-w-j)
2|Microchip|25LC010A|EEPROM|1Kbit(128byte)|SPI *2|[Link](https://www.mouser.com/datasheet/2/268/21832C-64496.pdf)
3|Atmel|AT93C46D|EEPROM|1Kbit(128byte)|SPI *1|[Link](https://www.marutsu.co.jp/contents/shop/marutsu/datasheet/AT93C46D.pdf)
4|FremontMicroDevices|FT25C08A|EEPROM|8Kbit(1KB)|SPI *2|[Link](http://www.fremontmicro.com/upload/2018/0524/1639202j84.pdf)
5|ON Semiconductor‎|CAT25160VI|EEPROM|16Kbit(2KB)|SPI *2|[Link](https://www.onsemi.com/pub/Collateral/CAT25080-D.PDF)
6|STMicroelectronics|M93C56|EEPROM|2Kbit(256byte)|SPI *1|[Link](https://www.st.com/resource/en/datasheet/m93c56-r.pdf)
7|AVR (Arduino)|ATmega328P|EEPROM|8Kbit(1KB)|Internal|[Link](https://avr.jp/user/DS/PDF/mega328P.pdf)|
8|Microchip|SST25VF512A|FlashROM|512Kbit(64KB)|SPI *2|[Link](http://ww1.microchip.com/downloads/en/DeviceDoc/25090A.pdf)
9|winbond|W25X20CLSNIG|FlashROM|2Mbit(256Kbyte)|SPI *2|[Link](https://www.winbond.com/resource-files/w25x20cl_a02.pdf)
10|Cypress|S25FL116K|FlashROM|16Mbit(2MB)|SPI *2|[Link](https://www.cypress.com/file/196886/download)
11|Macronix|MX25L512EMI|FlashROM|512Kbit(64KB)|SPI *2|[Link](https://www.macronix.com/Lists/Datasheet/Attachments/7398/MX25L512E,%203V,%20512Kb,%20v1.4.pdf)
12|Renesas|RL78/G13|FlashROM|32Kbit(4KB)|Internal|[Link](https://www.renesas.com/jp/ja/products/software-tools/tools/self-programming-library/data-flash-libraries.html)|

*1 Intel ? / *2 [JESD251](https://www.jedec.org/standards-documents/docs/jesd251)

# 検証手順
- RL78, Arduino 以外は全て mbed LPC1768 で制御した。
- 一定の領域に同じ値を書き込んだ後に読みだして値が一致することを確認した。
- 書き込む値は一致の確認後に1加算していき、一致しなかった時点で計測終了としている。
- 不一致になった後100回読み出しを行った。
- 処理時間の変化を調べるため消去・書き込み時間の最小・平均・最大時間も計測した。

# 結果：書き込み回数

||   |仕様<br>保証年数|仕様<br>保証回数|計測結果<br>書き込めた回数|計測結果<br>現象|
|---|---|-------:|-------:|-----:|-----|
1|BR93L46|40 Years|1,000,000|9,559,002|データ不一致
2|25LC010A|200 Years|1,000,000|7,922,668|データ不一致
3|AT93C46D|100 Years|1,000,000|2,107,287|データ不一致
4|FT25C08A|100 Years|1,000,000|2,388,904|データ不一致
5|CAT25160VI|100 Years|1,000,000|6,521,290|データ不一致
6|M93C56|200 Years|25℃: 4,000,000<br>85℃: 1,200,000|18,529,259|データ不一致
7|ATmega328P|100 Years|100,000|8,158,577|データ不一致
8|SST25VF512A|100 Years|Typ: 100,000<br>Min: 10,000|369,833|データ不一致
9|W25X20CLSNIG|20 Years|100,000|1,034,877|データ不一致
10|S25FL116K|2 Years<br>20 Years|100,000<br>10,000|690,000<br>800,314|消去未完了 *1<br>データ不一致
11|MX25L512EMI|20 Years|100,000|1,537,320|データ不一致
12|RL78(DataFlash)|1 Years<br>5 Years<br>20 Years|TYP: 1,000,000<br>100,000<br>10,000|19,474,131|データ不一致
*1 690,000前後の時点で消去がいつまでも完了しない現象が発生した。

# 結果：書き込み時間
最小、平均、最大時間に差があるものは分けて時間を記載している。

|||仕様|計測結果<br>回数=初期|計測結果<br>回数=破損時|書き込みサイズ
|---|---|---|---:|---:|---|
1|BR93L46|Max: 5.0ms|3.579ms|3.579ms|128byte
2|25LC010A|Max: 5.0ms|3.176ms|3.189ms|16byte (1page)
3|AT93C46D|Min: 0.1ms<br>Typ: 3.0ms<br>Max: 5.0ms|2.506ms|2.524ms|128byte
4|FT25C08A|Max: 5.0ms|1.159ms|1.160ms|32byte
5|CAT25160VI|Max: 5.0ms|1.373ms|1.374ms|32byte
6|M93C56|Max: 5.0ms|2.844ms|2.862ms|512byte(16bit x 256)
7|ATmega328P|3.6ms(1byte)|3.312ms(1byte)<br>106ms(32byte)|3.312ms(1byte)<br>106ms(32byte)|32byte
8|SST25VF512A|20us(1byte)<br>5.120ms(256byte)|5.414ms|5.415ms|256byte
9|W25X20CLSNIG|Typ: 0.4ms<br>Max: 0.8ms|Min: 0.146ms<br>Avg: 0.296ms<br>Max: 0.304ms|Min: 0.165ms<br>Avg: 0.316ms<br>Max: 0.587ms|256byte (1page)
10|S25FL116K|Typ: 0.7ms<br>Max: 3.0ms|0.579ms|0.585ms|256byte (1page)
11|MX25L512EMI|Typ: 0.6ms<br>Max 3.0ms|Min: 0.172ms<br>Avg: 0.540ms<br>Max: 0.544ms|Min: 0.172ms<br>Avg: 0.540ms<br>Max: 0.544ms|256byte(1Page)
12|RL78(DataFlash)|Typ: 11.750ms<br>Max: 115.824ms|11.124ms|11.124ms|256byte

# 結果：消去時間
今回の検証対象のうち消去が必要なのはFlashROMのみ。

| |  |仕様|計測結果<br>回数=初期|計測結果<br>回数=保証回数|計測結果<br>回数=破損時|消去<br>サイズ|
|---|---|---------|----------------------------:|----------------------:|------:|---|
8|SST25VF512A|Max: 25ms|Min: 16.48ms<br>Avg: 16.62ms<br>Max: 16.67ms|Min: 16.72ms<br>Avg: 16.72ms<br>Max: 16.74ms|Min: 16.69ms<br>Avg: 16.70ms<br>Max: 16.70ms|4KB<br>(Sector)
9|W25X20CLSNIG|Typ:  30ms<br>Max: 300ms|Min: 40.75ms<br>Avg: 43.54ms<br>Max: 47.64ms|Min: 84.44ms<br>Avg: 94.84ms<br>Max: 110.89ms|Min: 541.24ms<br>Avg: 608.34ms<br>Max: 611.71ms|4KB<br>(Sector)
10|S25FL116K|Typ:  50ms<br>Max: 450ms|Min: 43.04ms<br>Avg: 47.81ms<br>Max: 51.72ms|Min: 70.15ms<br>Avg: 77.55ms<br>Max: 86.78ms|Min: 235.81ms<br>Avg: 266.95ms<br>Max: 341.91ms|4KB<br>(Sector)
11|MX25L512EMI|Typ: 40ms<br>Max: 200ms|Min: 27.81ms<br>Avg: 31.21ms<br>Max: 33.70ms|Min: 53.36ms<br>Avg: 57.96ms<br>Max: 63.98ms|Min: 827.19ms<br>Avg: 949.35ms<br>Max: 1,090.39ms|4KB<br>(Sector)
12|RL78(DataFlash)|Typ:   6.15ms<br>Max: 273.59ms|Min: 5.75ms<br>Avg: 5.75ms<br>Max: 5.75ms|Min: 5.75ms<br>Avg: 5.82ms<br>Max: 11.10ms|Min: 209.72ms<br>Avg: 209.72ms<br>Max: 209.72ms|1KB<br>(Block)

# 結果：詳細
- 保証回数の2~19倍書き込むことができ、保証回数を下回るものは無かった。
- 消去・書き込み時間も保証回数内であれば仕様の最大時間を超えるものは無かった。  
ただし、保証回数を超えた場合、一部の FlashROM の消去時間が仕様を大幅に超えた。  
例：W25X20CLSNIG : 仕様Max 300ms、計測結果 611ms
- 仕様の範囲内であっても FlashROM の消去時間は消去回数に比例して長くなる。  
下記は W25X20CLSNIG の消去回数と消去時間で、緑の縦線が最小保証回数である。  
![8d05af2bfebbbe3eb86e5e4df69c1958.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154323/8b2c42e0-1fc7-6f47-496d-7a3fee12e47a.png)
- どの EEPROM/FLASHROM もbit単位で破損した。また破損するbit位置はチップごとに異なる。
- AT93C46D や M93C56 は複数アドレスのbitが一度に破損した。
- 破損時 AT93C46D, 25LC010A-IP などは0を書き込んだbitが1と読み出せた。  
MX25L512EMI, SST25VF512A などは1を書き込んだbitが0と読み出せた。  
- S25FL116K は消去も書き込みも完了せず、完了を待たずに読みだしたところ  
0x39を書いた全領域から0x00が読み出せた。  
- 破損後に消去/書き込みをリトライすると正常に消去/書き込みができたが、  
次の破損までの回数はチップごとに異なる。
 - EEPROM : M93C56 : 3回
 - EEPROM : AT93C46D : 44回
 - EEPROM : BR93L46 : 5,002回
 - FlashROM : MX25L512EMI : 369,439回
 - FlashROM : W25X20CLSNIG : 2回
- 一度破損したbitはリトライ後でも最初にデータが破損した。
- 破損後に複数回読み出すと正常な値の場合と、破損した値の場合があった。  
下記は W25X20CLSNIG が破損時に読み出しだけを繰り返したログで、  
1,2,3,9回目のみ期待値02が03に化けている。  
![bff419f747328fe224eb11b28a984b86.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154323/071cc714-c58a-603e-7349-d7094303c84d.png)  
下記は AT93C46D が破損時に読み出しだけを繰り返したログで、期待値011Eが211Eに化けている。  
![1be5e7e3111bc85cb2e8e75824dd381c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154323/73c9232f-329d-744c-1ecf-be345333b967.png)


# 考察
EEPROM/FLASHROM のエラー処理設計を行うための考察。

* 保証回数を超えると読み出すたびに正常値・異常値が変わるチップがあるため、  
保証回数を超える書き込みを行う設計は避けるべき。  
例えば「書き込み直後にベリファイして正常な間は書き込み続ける」ような設計にした場合  
ベリファイ時点では正常でも、次の読み出し結果が正常である保証はない。
* 保証回数を超えた場合だが、消去/書き込みが完了しないチップがあったため、  
完了をポーリングする場合はタイムアウトを設けたほうがいいかもしれない。
* 保証回数内であってもFlashROMの消去時間は消去/書き込み回数に比例して長くなるため、  
それを考慮して設計を行う必要がある。

#補足
* RL78の内蔵データフラッシュのように、消去・書き込み回数が増えると  
保持できる年数が減ると思われるが検証できていない。
* 各種1つずつしか検証していないため個体差は検証できていない。
* 当検証は保証回数内であればベリファイが不要であることを示す検証ではない。  
例えば、保証回数内であってもノイズで信号線のH/Lが変わり読み書きするデータが化ける可能性はある。

#参考URL
* [ＰＩＣ耐久試験](http://madlabo.oops.jp/MAD/0026/0026.htm)
* [EEPROM書換え上限テスト](https://wentwayup.tamaliver.jp/e396481.html)
* [EEPROMドライバソフト開発のノウハウ](https://www.softech.co.jp/mm_131002_firm.htm)
* [マイコンによるNOR型フラッシュメモリ制御](https://www.softech.co.jp/mm_090603_firm.htm)
* [JESD251 : EXPANDED SERIAL PERIPHERAL INTERFACE (xSPI)](https://www.jedec.org/standards-documents/docs/jesd251)