top >
技術情報 >
「Interface」 2004年12月号
|
NAND型フラッシュの読み出し/書き込み操作
|
|
NAND型フラッシュの大きな特徴として,読み出しや書き込みを,シーケンシャルに実行する点があげられます.メモリにアクセスするには,
まず所定のコマンドを投入してから,メモリのアドレスを必要サイクル分投入します.そのうえで必要なデータの読み出しや書き込みが実行できます.
NOR型フラッシュのようにメモリ空間上にメモリ・セルがマッピングされ,ランダム・アクセスできる構造にはなっていません.この点はメモリというより,
むしろHDDなどに近いアクセス方式となっています.
フラッシュの読み書きはページと呼ばれる528(512+16)バイト単位で実行します.
1ページは,512バイトのデータ部と16バイトの冗長部に分けられます.
データ部には通常のデータを格納し,冗長部にはECCデータや不良ブロック・マーク,そのほかの管理情報を格納するのが一般的な使い方です.
ちなみにデータ部と冗長部のメモリ・セルには何ら違いはなく,このように使い分けると便利なように内部の制御回路が構成されており,
それにあわせてコマンドが用意されているにすぎません.データ部よりも冗長部のほうが不良率が低いといった差はありません.
ブロックはフラッシュの一括消去の単位で,32ページ(16Kバイト)で構成されています.
ページとブロックにはそれぞれアドレスとして0から番号が割り当てられています(図2).
|
図2 ブロックとページの構成 |
|
 |
|
|
フラッシュへの読み書きはすべて8ビットないしは16ビットのデータ・ポートを経由して行われます.
データ・ポートで読み書きされるデータを区別するために,入出力用の制御信号として_CLE(Command Latch Enable),_ALE(Address Latch Enable),
_RE(Read Enable),_WE(Write Enable)があり,
この組み合わせでコマンド,アドレス,データ(読み込み/書き込み)を区別します.NAND型フラッシュの制御信号一覧を表2に示します.
|
表2 NAND型フラッシュの制御信号一覧
|
_CE
|
チップ・イネーブル
|
_WE
|
ライト・イネーブル
|
_RE
|
リード・イネーブル
|
CLE
|
コマンド・ラッチ・イネーブル
|
ALE
|
アドレス・ラッチ・イネーブル
|
_WP
|
ライト・プロテクト
|
RY/_BY
|
レディ・ビジー出力
|
I/O
|
コマンド・アドレス・データ入出力
|
|
多くのデバイスと同様に_CE(Chip Enable)があり,バス・マスタのフラッシュ・チップへのアクセスを明示します.
フラッシュの内部状態を示すRY/_BY信号もあり,ドライバ・ソフトウェアでこの信号レベルを監視してチップの動作状態を判別します.
NAND型フラッシュは上記のとおり,CPUから見た場合にはメモリというよりもパラレル・ポート付きのI/Oデバイスのように見えます.
フラッシュをCPUに接続する場合には,何通りかの方法があります.
1) すべての制御信号,データ・ポートをGPIOに接続
すべての制御線とデータ・ポートをGPIOに接続し,チップの選択や読み込み/書き込みのタイミング制御などはすべてプログラムで実現します
〔図3(a)〕.
|
図3-a GPIO接続 |
|
 |
|
2) メモリ・バスに接続
CPUのメモリへのリード/ライトでそのままデータ・ポートを読み書きできるように,簡単なグルー・ロジックを介して接続する方法です.
メモリ・バスの制御信号で_ALE,_CLE,_RE,_WEを作り,_CEとRD/_BYのみをGPIOに接続します〔図3(b)〕.
|
図3-b メモリ・バス接続1 |
|
 |
|
NAND型フラッシュには“CE Don’t Care”というタイプが存在します〔図3(c)〕.通常のNANDフラッシュでは,
コマンド投入からデータの読み書き完了まで,_CEピンをアサートし続けていなければいけません.このため_CEピンはGPIOにつなぐなどして,
プログラムで明示的に制御しなければなりませんが,“CE Don’t Care”は_CEのレベルに関係なく読み書きの操作をできるようにしてあるので,
メモリ・バスに出ている_CSなどを直接つないでNANDフラッシュを制御できるようになります.
|
図3-c メモリ・バス接続2 |
|
 |
|
3) 専用のコントローラを介して接続
ECC回路やデータの読み書き,1ページ分の内部バッファなどを持ったコントローラに接続し,NANDの制御をこのコントローラで行う方法です.
プログラムからは,コントローラのレジスタへのアクセスと,内蔵SRAMバッファへのアクセスだけで済みます.最近のアプリケーション・プロセッサは,
NANDコントローラを内蔵したものがいろいろと出始めています.
|
|
|
フラッシュに格納されたデータを読み出す場合には,
チップのレディ状態でデータ・ポートに読み出しコマンド(0x00)と数バイトのアドレスを投入した後,デバイスのレディ状態を待ちます.
この間にフラッシュ内部では各セルの値がリード・バッファに読み出されます.528バイトすべて読み込まれるとRY/_BYピンのレベルがレディになります.
これを待ってからデータ・ポートからのデータを読み込みます.
メモリ・セルからリード・バッファへの読み出しには10〜20μsかかりますが,
この時間はリアルタイムOSのコンテキスト・スイッチの時間と大差ない非常に短い時間です.
そのため,コンテキスト・スイッチが起こるような手法,たとえばドライバ・プログラムで時間待ちのsleep()を入れたり,
RY/_BYを割り込みで受けるような手法は使わず,単純なbusy loopで待ち受ける実装がもっともシンプルで性能の出やすい実装方法ということになります.
|
|
|
フラッシュにデータを書き込む場合は,チップのレディ状態でデータ入力コマンド(0x80)を投入した後,数バイトのアドレスを投入し,
引き続きデータを528バイト投入します.投入したデータは内部のバッファに溜め込まれます.データ投入後に書き込みコマンド(0x10)を投入すると,
チップ内部で書き込み動作が開始されます.書き込み動作中はRY/_BYピンがアサートされているので,GPIOポートでこれを監視するか,
フラッシュにステータス・コマンドを投入して内部のステータスを読み出して監視をし続けます.データの書き込みにはおおよそ200μsかかります.
リードの場合と同様にこの間をbusy loopで待つか,もしくはsleep()などでいったんCPU時間をほかのタスクに回すかは,
システムの特性によって決まるでしょう.
|
|
|
フラッシュ上のブロックを消去する場合は,次のように操作します.チップのレディ状態で消去コマンド(0x60)を投入し,
その後ブロック番号をアドレスとして投入,最後に消去開始コマンド(0xD0)を投入します.これで指定したブロックの消去が開始されます.
ブロックの消去には数msかかります.消去終了は書き込みと同様にRY/_BYピンのレベルを確認するか,
ステータス・リード・コマンド(0x70)でステータスを取得して確認します.
書き込み動作と消去動作完了後には,必ずステータス・リード・コマンド(0x70)を使って正常終了したかどうかを確認してください.
ステータスがビジーの間のチップ・ステータスは意味がないので無視してください.
ステータスがレディになった時点で書き込みや消去の処理結果がチップ・ステータスとして示されます.これがPassならば処理完了ですが,
Failになっている場合には,書き込み不良や消去不良なので,そのブロックを不良ブロックと認定して,しかるべき退避処理を実施する必要があります.
消去時の不良ブロック発生については,対象ブロックに有効なデータはないので,そのブロックを不良ブロックとして管理情報を登録し,
これ以降書き込みなどに使われないようにします.書き込み時の不良ブロックの場合には,そのブロックを不良ブロックとして登録するだけではなく,
すでにそのブロックに正しく書き終わっているデータを,
別の正常な空きブロックに書き写したうえで再度正常に終わらなかったデータの書き込み処理を再実行します.
|
|
|
|
|