10

私はAVRのEEPROMの寿命を最大化するArduinoライブラリに取り組んでいます。保存する変数の数を取得し、残りを実行します。これは私の試みですが、すべての場合に機能するとは限りません。

背景情報

Atmelによると、各メモリセルの定格は100,000回の書き込み/消去サイクルです。また、ウェアレベリングの実行方法を説明するアプリケーションノートも提供します。アプリケーションノートの概要は次のとおりです。

2つのメモリアドレス間で書き込みを交互に行うことにより、消去/書き込みを200,000サイクルに増やすことができます。3つのメモリアドレスにより、300,000回の消去/書き込みサイクルなどが可能になります。このプロセスを自動化するために、ステータスバッファを使用して、次の書き込みがどこにあるべきかを追跡します。ステータスバッファもパラメータバッファと同じ長さである必要があります。これは、ウェアレベリングも実行する必要があるためです。次の書き込みのインデックスを保存できないため、対応するインデックスをステータスバッファにインクリメントします。

これが例です。

   <------------------- EEPROM -------------------->  
   0                                               N
   -------------------------------------------------
       Parameter Buffer    |     Status Buffer     |
   -------------------------------------------------

   Initial state.
   [ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ]

   First write is a 7. The corresponding position
   in the status buffer is changed to previous value + 1.
   Both buffers are circular.
   [ 7 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 ]

   A second value, 4, is written to the parameter buffer 
   and the second element in the status buffer becomes
   the previous element, 1 in this case, plus 1.
   [ 7 | 4 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | 0 | 0 | 0 ]

   And so on
   [ 7 | 4 | 9 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 ]

次の書き込みが発生する場所を決定するために、要素間の違いを調べます。前の要素+1が次の要素と等しくない場合、次の書き込みが発生する場所です。例えば:

   Compute the differences by starting at the first
   element in the status buffer and wrapping around. 
   General algo: previous element + 1 = current element
   1st element:  0 + 1 = 1 = 1st element (move on)
   2nd element:  1 + 1 = 2 = 2nd element (move on)
   3rd element:  2 + 1 = 3 = 3rd element (move on)
   4th element:  3 + 1 = 4 != 4th element (next write occurs here)

   [ 7 | 4 | 9 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 ]
                 ^                       ^
                 |                       |

   Another edge case to consider is when the incrementing values
   wrap around at 256 because we are writing bytes. With the
   following buffer we know the next write is at the 3rd element 
   because 255 + 1 = 0 != 250 assuming we are using byte arithmetic.

   [ x | x | x | x | x | x | 254 | 255 | 250 | 251 | 252 | 253 ]
                                          ^
                                          | 

   After we write at element 3 the status buffer is incremented 
   to the next value using byte arithmetic and looks like this.
   255 + 1 = 0 (wrap around)
   0 + 1 != 251 (next write is here)

   [ x | x | x | x | x | x | 254 | 255 |  0  | 251 | 252 | 253 ]
                                                ^
                                                | 

上記の例は、1つの変数のEEPROMの寿命を延ばす方法を示しています。複数の変数の場合、EEPROMを同じデータ構造で、バッファが小さい複数のセグメントにセグメント化することを想像してください。

問題

私は上で説明したもののための作業コードを持っています。私の問題は、バッファ長が256以上の場合にアルゴリズムが機能しないことです。これが何が起こるかです。

   Buffer length of 256. The last zero is from
   the initial state of the buffer. At every index
   previous element + 1 == next element. No way to
   know where the next write should be.

   <-------------- Status Buffer ------------>
   [  1  |  2  | ... | 253 | 254 | 255 |  0  ]


   A similar problem occurs when the buffer length
   is greater than 256. A lookup for a read will think
   the next element is at the first 0 when it should be at 
   255.
   <-------------------- Status Buffer ------------------>
   [  1  |  2  | ... | 253 | 254 | 255 |  0  |  0  |  0  ]

質問

上記の問題をどのように解決できますか?次の要素をどこに書くべきかを追跡するためのより良い方法はありますか?

4

2 に答える 2

17

一般的なEEPROMの寿命延長についてのいくつかの考え:

  1. EEPROMセルは通常、2ステップの操作で(ハードウェアによって)書き込まれます。最初にセルが消去されます。つまり、すべて1に設定され(0b11111111 = 0xff)、次に書き込まれるビット(事実上0のビットのみ)です。実際に書かれています。ビットは、実際の書き込み操作によってのみ0に設定できます。ビットを0から1に変更するには、セル全体を消去してから、新しい値を再書き込みする必要があります。

  2. EEPROMセルに書き込まれるのと同じ値がすでに含まれている場合(多かれ少なかれ(再)書き込まれるデータの場合があります)、セルに書き込む必要はまったくなく、削減されます。その書き込み操作を0に変更します。常に新しい値を書き込むのではなく、セルの内容をチェックして、セルの内容を書き込む必要があるかどうかを判断することをお勧めします。

  3. 上記の組み合わせにより、新しい値に1ビットがあり、格納されている値が0ビットである場合(つまり、の場合StoredValue & NewValue != NewValue)、セルは書き込みの前にのみ消去されるというアプローチになります。新しい値()に必要な0-> 1ビット遷移がない場合は、セルを消去する必要はありませんStoredValue & NewValue == NewValue

  4. AVRは、上記のメカニズムをサポートするために、EEPROMセルをそれぞれ消去および書き込みするための個別の命令を提供します。

  5. もちろん、EEPROMへのデータ転送の最悪の場合の速度は、単なる消去/書き込み操作ではなく、読み取り-比較-消去-書き込みを実行すると低下します。ただし、これにより、一部/ほとんどのセルの消去/書き込み操作が完全にスキップされる可能性があり、相対速度のペナルティが軽減される可能性があります。

現在の問題については、上記の点について考えてください。次の書き込み位置を格納するためにシングルビットを使用してみませんか?

例:

ステータスバッファはすべてのものに初期化されます:

Bit number: 0123 4567 89AB CDEF
Value:      1111 1111 1111 1111

EEPROMの値にアクセスする前に、ステータスバッファの最初の1ビットを見つけてください。そのビットの数は、(循環)パラメータバッファの現在の「ヘッド」のアドレスを表します。

パラメータバッファを進めるたびに、ステータスバッファの次のビットを0に設定します。

Bit number: 0123 4567 89AB CDEF
Value:      0111 1111 1111 1111

それから

Value:      0011 1111 1111 1111

それから

Value:      0001 1111 1111 1111

等々。

これはセル全体を消去せずに実行できるため、更新のたびにステータスバッファの1ビットのみが「摩耗」します。書き込まれるデータに0ビットが1つしかない場合も同様です。
たとえば、保存されている値を0111新しい値0011に変換するには、書き込むデータを1011data = ( newValue XOR oldValue ) XOR 0xff)にして、実際に変更したい1つのビットを除いてすべてのビットを変更しないでください。

ステータスバッファが使い果たされると(すべて0)、完全に消去され、すべてが最初からやり直されます。

ここでの明確なプラスは、パラメータバッファのユニットごとに1ビットのステータスのみを維持する必要があることです。これは、Atmelアプリケーションノートと比較してメモリの1/8しか消費しません。さらに、ステータスバッファでの読み取り操作の1/8のみが必要になるため、次の書き込み場所の検索もはるかに高速になります。(編集:EEPROMの読み取りはパフォーマンス面でほぼゼロのコストで行われるため、正しくありませんが、必要なビットシフトには数十サイクルかかる場合があります。)

ただし、別の注意事項:256以上のパラメータバッファユニットを使用することは実際に役立つと思いますか?たとえば、デバイスで使用可能な合計1024バイトのEEPROMを処理する場合、ユニットは非常に小さくなります。-そして、100000サイクルに256を掛けると、非常に多くの書き込み操作が必要になります。その数が必要と思われる場合は、アルゴリズムに問題があるか、EEPROMを目的に使用しないでください。別の方法として、一部のシナリオでは外部NVRAMが適しています。

アクセス時間もここでの側面かもしれません。たとえば、256バイトのステータスバッファを使用してパラメータバッファで3バイトサイズの要素を検索して読み取ろうとすると、最悪の場合、256(+3)の読み取り操作が必要になります。ケース-途方もないオーバーヘッド!

劣化の方法と理由を含む、EEPROMセルの動作に関する非常に説明的なドキュメントがあります。

STMicroelectronics:「設計者がSTMicroelectronicsシリアルEEPROMを最大限に活用する方法」、アプリケーションノートAN2014

于 2012-05-19T23:34:33.527 に答える
2

カウンターの代わりに、データ要素に単純な「ダーティ」ビットを使用することをお勧めします。最後に書き込まれた要素のスキャンが遅すぎる場合、または不良なEEPROMセルを追跡するなどの複雑なことをしたい場合を除いて、カウンターやカタログを用意しても意味がありません。

アルゴリズムは非常に単純です。書き込むすべての要素に「ダーティ」ビットを設定し、最後の要素を読み取るか、新しい要素を書き込む必要があるときにこのビットをスキャンします。クリーンスポットが足りなくなったら、すべての要素を消去するか、(Arduinoの場合)「ダーティ」ビットの値を反転して最初から始めます。必要に応じて、ここに詳細な説明を書きました。

于 2017-05-09T16:43:40.707 に答える