STM32およびMSP430マイクロコントローラーのフラッシュメモリ内のデータの信頼性の高い保存と更新

多くの場合、変更されたデータ(構成など)をマイクロコントローラーのフラッシュメモリに保存するタスクがあります。 解決策は簡単に思えますが、データ更新の信頼性を確保することは、いつでも電源を切ることができれば非常に重要であり、チェックサムを使用しても問題は完全には解決されません。 この記事から学ぶことができます



実践したい人のために-STM32F4で動作するコード



この問題に対する古典的なアプローチは、データをフラッシュに書き込み、その後にチェックサムを書き込むことです。これにより、読み取り時にデータの整合性を検証できます。 著者がマイクロコントローラMSP430用に提案した回路は、このアプローチに基づいています。 ただし、2つの欠点があります。独立して更新できる部分にデータを保存することでメモリを節約したいという複雑さ、および記録時に電源をオフにしたときのデータの完全性の厳密な保証がありません。 整合性とは、次のことを意味します。

そのため、STM32に基づいて次のデバイスを開発する際に、前述の欠点のない、この問題を厳密に解決するための2回目の試みを行うことが決定されました。 しかし、最初に、私たちが対処している問題の本質を理解するためにフラッシュメモリがどのように設計されているかを見ていきます。



フラッシュメモリの仕組み



フラッシュメモリは、絶縁ゲートトランジスタ(MOSトランジスタ)の特別な変更に基づいています。 従来のMOSトランジスタは、絶縁体として機能する酸化物層でコーティングされたシリコンウェーハ上に形成されます。 シャッターと呼ばれる電極が酸化物の上にスプレーされます。 この電極に電圧を印加することにより、シリコンウェーハ上の2つの電極(ドレインとソース)間に流れる電流を制御できます。 これは、ゲートの正電荷が電子を引き付け、電子の伝導チャネルがゲートの下に形成されるために起こります。 ゲートから電圧を除去すると、伝導チャネルが消えます。







フラッシュメモリはフローティングゲートトランジスタを使用しています。 それらは、ゲートとチャネルの間の酸化物の厚さで全体から絶縁されたシリコンの島を持っています。 島が充電されていない場合、トランジスタは通常のトランジスタと同じように機能します。 ただし、島に一定数の電子が落ち着くと、正のゲート電荷が補償され、伝導チャネルが消滅します。







電子はデータの記録中にフローティングゲートに落ち、絶縁体をトンネルします。 このプロセスは、フィルムウィザードに明確に示されています。主なことは、障害物に気付かないように、よく加速し、ターゲットを確認することです。 電子は、チャネルに電流を流すことにより加速されます。







消去はより困難です-シャッターに電子を定着させる必要はありませんが、そこから電子を除去する必要があるため、分散できません。 したがって、単純にチャネルに正の電位を形成し、電子がチャネルに引き寄せられてトンネルに入るのを待ちます。 それが、消去が記録よりも数桁長い時間がかかる理由です。 STM32の場合、これは数秒から数秒です。 SSDなどのより高度なデバイスは、使い古されたトランジスタの在庫をサポートしますが、それらが不足すると、書き込み操作にかかる時間が大幅に増加します。



時間を節約するために、大きなブロック-セクターのメモリを消去します。 STM32の場合、最小サイズ(16キロバイト)には、下位アドレスに4つのセクターがあります。 STM32は1バイト、2バイト、または4バイトを書き込むことができます。 消去されたトランジスタは、論理ユニットとして読み取られます。 したがって、記録中に、記録されたデータの論理ゼロに対応するトランジスタのゲートに電子を配置します。 したがって、興味深い観察結果-同じバイトのビットを1つずつゼロに設定でき、一度にすべてを設定することはできません。 ゼロビットを1に設定する逆の操作は、消去なしでは不可能です。 1ビットを記録する場合、メモリの内容は変更されません。



可読性安定性の問題



データ記録時に電源を切るとどうなりますか? 一部のデータが記録されないことは明らかです。 そして、電源オフ時に書き留めたそのバイトまたは単語はどうなりますか? フローティングシャッターで記録する場合、異なる数の電子を取得できます。 多くの電子は0として読み取られ、1としてはほとんど読み取られません。これは、電子の境界数があることも意味します。 電源がオフになる前に、ゲートが境界に近い電子数を受け取った場合、読み取り時に、完全にランダムな要因に応じて0と1の両方を取得できます。 時間の経過とともに、電荷はシャッターから排出されるため、1を読み取る可能性が高くなります。 この非常に不快な機能により、チェックサムスキームでさえ信頼できなくなります。 パッケージの最後の単語に任意の量の検証情報を伴うことができるデータを記録した時点で電源がオフになった場合、今日ではデータを読み取ることができますが、明日は読み取ることができません。 さらに、現在消去されていると思われる領域に書き込む際に問題が発生します。今日はすべてのユニットのように読み取られるためです。結局、ゼロがそこに現れて明日データを破壊する可能性があります。



消去時に電源を切ると、同様の問題が発生します。 そうすることで、予測不可能な将来の動作を伴う完全に予測不可能なメモリ内容を取得します。 したがって、このような状況では、検出して再消去できる必要があります。 そのため、フラッシュメモリへの書き込みを処理するコードは、妄想が高まった状態で記述する必要があり、この妄想の程度が十分であるかどうかはわかりません。



データ整合性保証実装



これで、上記の意味でデータの整合性を保証するデータストレージスキームを検討する準備が整いました。 STMはフラッシュのサイズを節約しないため、保存を拒否して設計を簡素化し、すべてのデータを固定サイズの単一構造に結合するモデルを使用することにしました。 データを更新するとき、構造全体を記録します。 データの異なるバージョンがフラッシュメモリの以前に消去された領域に順次書き込まれます。 最新の記録データは関連性があると見なされます。



システムは2つのレベルに分割され、データの整合性に関するさまざまな保証を提供します。 下位レベルにはデータプールがあり、以前に消去したセクターに連続してデータを書き込むことができます。 このレベルでのデータパケットの形式を以下に示します。







データ自体の後、32ビットワードへのアライメントが続き、その後にチェックサムが書き込まれます。 チェックサムがチェックバイトになった後、単純にゼロビットを書き込みます。 データパケットのこの部分をバイト単位で書き込みます。したがって、読み取り中にテストバイトに少なくとも1つのゼロビットがある場合、チェックサムが正しく書き込まれ、その内容が時間とともに変化しないことを確認できます。 テスト後の次のバイトはステータスです。 パケットを完了としてマークするゼロビットがここにあります。 読み取り中にこのゼロビットが見つかった場合、これは検証バイトも正しく書き込まれ、その内容は時間とともに変化しないことを意味します。 つまり、完全に記録されたデータを考慮することができ、時間の経過とともに意見が変わることはありません。 読み取り中に完了フラグが見つからなかったが、テストバイトにゼロビットがある場合、最後の2バイトを単純に上書きします。 チェックバイトですべての単一ビットが読み取られた場合、データはチェックサムに関係なく正しく書き込まれなかったと見なされます。



なぜこのような困難なのか、好奇心itive盛な読者は尋ねるかもしれません。 結局、チェックサムを簡単に書き換えることができ、時間の経過とともに変化しないことが保証されています。 はい、確かに、しかし毎回それをしなければなりません。 目標は



2番目のステータスビット-継続フラグ-を使用すると、すべてのユニットの読み取り元のメモリが消去されたと見なすことができるかどうかを判断できます。 次のデータブロックを書き込む前に、このフラグを設定します(ビットを0にリセットします)。 読み取り中にこのビットに1が表示された場合、次のバイトへの書き込みは試行されていません。 しかし、セクターが最初は空の場合はどうなりますか?消去されたかどうかを検討できますか? もちろん違います! しかし、このパラノイアの再発は対処するのが最も簡単です-何かを書き留める前にもう一度それを消去します。



そのため、一度読み取ると、データがさらに読み取られることを保証できます。 ただし、信頼性の高いデータウェアハウスの他のプロパティでは、すべてがそれほどバラ色ではありません。 場所が終わると、セクターを定期的に消去する必要があるという明らかな問題があります。 電源が切れると、新しいデータを書き留めるだけでなく、古いデータも失います。 やや目立たない問題は、誤って記録されたデータ(記録中の停電の結果)です。 時間が経つにつれて、そこに欠落ビットが表示されないことを保証することはできず、このデータを正しいものとして読み取り始めません。 レコードを誤っているとマークする追加のステータスビットが状況を保存できるように見えるかもしれませんが、そうではありません。 結局のところ、これらの余分なビットを記録すると電力が失われる可能性があり、その結果、問題が増えるだけです。 上記の回路は、元のレコードとまったく同じデータを記録するため、修正レコードを正常に使用します。したがって、停電のシーケンスが発生しても、最後に成功したレコードはフラッシュを安定状態にします。 もちろん、この形式では、説明したストレージは、ストレージの信頼性に対する高い要件を持たないアプリケーションで使用できます。 しかし、説明されているタイプの2つのストアに基づいて、説明されている欠点のない、より信頼性の高いオプションを作成できることがわかりました。 このようなストレージの図を次の図に示します。







上記のタイプの2つのデータプールには、ユーザーデータ(フラッシュの2つの異なるセクター)が格納され、サービスバイトが追加されます。 エポック番号とデータ無効のフラグ(「墓石」と呼ばれることが多い)を保存します。 現在のプールのスペースが足りなくなった場合、時代の数を1つ増やし、次の時代に書き込みを開始します。 最後に記録されたデータでプールを消去しないため、停電によってすべてのデータが破壊されることはもうありません。 次のレコードが発生するプールの番号は、紀元番号の最下位ビットに等しくなります。 システムの開始時に、エポックの番号(数値円上)を比較して、最後に記録されたプールを決定します。 不完全なレコードの安定性の問題も非常に簡単に解決されます。 最初に間違っていると思われるレコードを見つけた場合、実際のデータがある場合はそれを使用して、または存在しない場合は墓石を使用して新しいレコードを作成することで、単に「埋める」ことができます。



テストプロジェクト



ここにあります 。 プロジェクトは、 STM32-H405ボード用のIAR EWARMコンパイラでSTM32CubeMXを使用して作成されました。 STM32CubeMXを使用してプロジェクトをコンパイルしても、肯定的な感情しか残っていません。 細切れの木は特に楽しいです-私にとって魔法の領域であった部分は、マウスを数回クリックするだけで簡単になりました。 このプロジェクトは、STM32CubeMXを使用して再生成するだけで、他のSTM32プロセッサまたはコンパイラに簡単に適合させることができます。 データウェアハウスコードは、フラッシュを使用する作業が抽象インターフェイスを備えた別のモジュールに移動されるため、他のアーキテクチャへの適応も容易です。 このプロジェクトには、ウォッチドッグタイマーを使用してプロセッサをランダムにリセットする自動データウェアハウステストが含まれています。 さらに、プロジェクトにはUSB CDCプロトコルのテスト実装があり、受信したすべての回線を単純に送り返します。 2つの質問に興味があったので追加しました。 まず、USBスタックの実装について知っている問題はどうなりますか。 何もないことが判明しました-古い問題は修正されておらず、新しい問題は現れていません。 どうやらこれはキャンペーンの方針です-ZLPを知っている人は-自分でそれを行い、知らない人は-サポートにお金を払うでしょう。 第二に、プロセッサがフラッシュからの命令の選択を停止できるため、フラッシュの消去がUSBの動作にどのように影響するかが興味深いことでした。 影響しないことが判明しました。



更新-MSP430のオプション



リポジトリに追加されたMSP430のテストプロジェクト。 フラッシュメモリでの操作を実装するモジュールのみが異なり、残りのコードは共通です。 LaunchPadでテスト済み。 テストではタイマーが作動し、タイマー出力は直接グランドに接続されました。 510Ωの抵抗を介してボードに電力が供給されたため、タイマーがトリガーされると、電力が大幅に低下し、マイクロコントローラーがリセットされ、現在のすべてのフラッシュ操作が中断されました。 このテストでは、フラッシュで100万件のレコードを正常に完了し、3時間半かかりました。 この間、512バイトのセクターが約20,000回消去され、電源は約5,000回オフになりました。 結果は、2つの別々の制御セクターのエントリと比較して確認されました。 テスト中にエラーは検出されませんでした。



All Articles