AN-1452: ADuCM3027/ADuCM3029 のフラッシュ・メモリを利用したEEPROM エミュレーション

はじめに

不揮発性のデータ・ストレージは、多くの組込みシステムに欠くことのできないものです。ブートアップ構成、補正係数、ネットワーク関連情報などのデータは、通常、EEPROM(Electronically Erasable Programmable Read Only Memory)デバイスに保存されます。これらのデータの保存にEEPROMを使用する利点は、EEPROM 上の他のロケーションの内容に影響を与えることなく、1 バイト単位でデータを書き換えたり更新したりできることです。

ADuCM3027/ADuCM3029 は、フラッシュ・メモリを内蔵した超低消費電力のマイクロコントローラ・ユニット(MCU)です。ADuCM3027/ADuCM3029には、72ビット幅のデータ・バスを備えた512kB の組込みフラッシュ・メモリがあり、このデータ・バスにより1 回のアクセスで、32 ビット・ワードのデータ2 個と、それに対応する8 ビットのエラー訂正コード(ECC)バイトを送ることができます。このECC のチェックはADuCM3027/ADuCM3029 のユーザ・スペースではデフォルトで有効化されており、これによってフラッシュの初期化機能が期待どおりに動作します。ECC チェックは、ADuCM3027/ADuCM3029 のフラッシュのユーザ・スペース全域で有効化されています。読出し動作でECC エラーがレポートされると、ECC エンジンは1 ビット・エラーの場合には自動的に訂正し、2 ビット・エラーの場合は単に検出をレポートします。フラッシュで読出しが行われると、適切なフラグがADuCM3027/ADuCM3029 のステータス・レジスタにセットされます。割込みが生成されると、割込みの原因となったECC エラーのソース・アドレスがFLCC0_ECC_ADDR レジスタで読出し可能となり、割込みサービス・ルーチン(ISR)によって読出しが行われます。

内蔵フラッシュ・メモリでEEPROMをエミュレートすれば、設計からEEPROM を除外できるので、部品表(BOM)コストを削減できます。したがって、ソフトウェアもより単純化されます。

背景

通常、フラッシュ・メモリはページの配列として構成されます。ADuCM3027 の1 ページには2 kB の容量があります。ページの内容は、データを書き込む前に消去する必要があります。消去動作はページ全体に対して行われますが、読出しや書込みは、アドレス指定可能な1 つのロケーション(バイトまたはワード)に対して行うことができます。

アドレス指定可能な1 つのロケーションを対象とする読出しと書込みには、次のような課題があります。

  • 1 バイト幅のデータの読出しと書込み。
  • 他のロケーションにあるデータを維持しながら、任意のロケーションにあるデータを消去または更新すること(フラッシュ・メモリの消去はページ全体に対して行われるため)。

このアプリケーション・ノートでは、図1 に示すように、ADuCM3027/ADuCM3029 デバイスと内蔵フラッシュ・メモリを使用してEEPROMをエミュレートするソフトウェアについて説明します。

図1. ADuCM3027/ADuCM3029 の内蔵フラッシュとEEPROM システムの概要
図1. ADuCM3027/ADuCM3029 の内蔵フラッシュとEEPROM システムの概要

動作原理

EEPROM をエミュレートするには、フラッシュ・メモリの一部をエミュレーション専用に割り当てる必要があります。ほとんどのEEPROM では、1 回の書込みコマンドで更新できるデータは1 バイトだけです。ただし、フラッシュ・メモリ・デバイスには、複数バイトを1 回で書き込める機能があり、2 回の書込み動作の間に消去シーケンスを実行すれば、データの更新も複数バイトで実行できます。1 バイトの書込みと読出しが可能なEEPROM をフラッシュ・メモリでエミュレートするには、EEPROM 動作と同様の読出し、変更、書込みシーケンスを設定する必要があります。

図2. ADuCM3027/ADuCM3029 フラッシュEEPROM エミュレーション・ソフトウェアの構造
図2. ADuCM3027/ADuCM3029 フラッシュEEPROM エミュレーション・ソフトウェアの構造

このセクションに示す手順では2 つのフラッシュ・ページを使用しますが、これらのページを3 ページ以上に拡張して、セクタ・タグで構成される複数のセクタに分割することができます。このセクタ・タグは、現在処理中のセクタと、そのセクタに書き込まれるデータのバイト数に関する情報を提供します。どのセクタも最後のロケーションがセクタ・タグ用に予約されており、そのサイズは、フラッシュ・メモリのデータ・バス幅に等しいサイズです。フラッシュ・ページ内のセクタ・サイズとセクタ数は、エミュレートされるEEPROM のサイズに依存します。

EEPROM

EEPROM の書込みおよび読出し機能には、EEPROM のデータやアドレス情報など、アプリケーション・コード入力の処理が含まれます。EEPROMのAPI(Application Programming Interface)は、フラッシュ・インターフェースの条件に従ってデータやアドレス情報を処理し、提供します。

EEPROM の初期化

EEPROM 動作を初期化することで、EEPROM のサイズとエミュレートするEEPROM のデータのワード長が設定されます。このアプリケーション・ソフトウェアでは、EEPROM エミュレーションがデータの完全性を維持できるように2 ページ分のフラッシュ・ページが予約されているため、エミュレートするEEPROMの最大サイズは2kB(1 フラッシュ・ページ)です。同じアプリケーション・ソフトウェアでフラッシュ・ページの予約が2 ページから4 ページに拡張されている場合は、この制限も拡張できます。ワード長は8 ビットから最大64 ビットまでの範囲でユーザが設定できます。init_eeprom(uint16_t eeprom_size, uint8_t word_length)関数の詳細については、表1 を参照してください。

表1. EEPROM 初期化関数の説明 – init_eeprom(uint16_t eeprom_size, uint8_t word_length)
パラメータ 説明 戻り値
eeprom_size エミュレートするEEPROM のサイズ。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。
word_length エミュレートするEEPROM に書き込まれるデータ・ワード長。有効な値は、8、16、32、64 です。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。

EEPROM への書込み

EEPROM の書込み動作のフローチャートを図3 に示します。EEPROMの書込み動作手順は以下のとおりです。

  1. find_current_sector()関数を呼び出して、現在のセクタを検索します。この検索は、セクタ・タグと、それに対応するセクタ・タグ値に基づいて行われます。返される値は、現在のセクタ開始アドレス(フラッシュ・メモリ上の物理ロケーション)です。
  2. 現在のセクタ開始アドレスに基づいて、EEPROMアドレスをフラッシュ・アドレスに変換します。ADuCM3027/ADuCM3029 のフラッシュ・メモリのデータ・バスは72 ビット幅で、エミュレートするEEPROMのデータ・バスは8 ビット幅なので、ソフトウェアがEEPROMアドレスから必要シフト数を決定します。
  3. 得られたフラッシュ・アドレスからデータを読み出します。そのデータが0xFF に等しい場合、書き込むデータはまず2つの32 ビット・データ(pack_lower_data()とpack_upper_data())にまとめられ、64 ビット幅のデータがフラッシュ・メモリに書き込むために用意されます。
  4. write_flash()関数を呼び出し、フラッシュ・コントローラに対して書込みコマンドを実行します。この関数の入力パラメータは、フラッシュ・メモリ・アドレス、最下位ビット(LSB)データ・パケット、最上位ビット(MSB)データ・パケットです。
  5. フラッシュ・メモリへの書込み動作が完了した後、update_tag()関数を呼び出して、現在のセクタのセクタ・タグを更新します。
図3. EEPROM の書込み動作
図3. EEPROM の書込み動作

得られたフラッシュ・アドレスにデータが既に存在する場合、データ読取り関数は0xFF を返しません。この場合、得られたフラッシュ・アドレスの前後にあるデータは、move2nextsector()関数を呼び出すことによって、次のセクタ、つまり隣接セクタに移動します。LSB とMSB のデータ・パケットに変換されたEEPROM データは、次のセクタの新しいフラッシュ・アドレスに書き込まれます。したがって、既に書込み済みのEEPROM のロケーションに書込みが行われると、データはその都度、変更されたデータを格納するロケーション含む次のセクタに移されます。

新しいセクタが次ページにある場合は、データ移動後に前ページ上でerase_flash(page_number)を呼び出すことによって、フラッシュ・ページ消去コマンドが送出されます。全てのアドレス・レジスタが、move2nextpage()関数によって更新されます。

write_eeprom(uint16_t addr_eeprom, uint8_t data_eeprom)関数の詳細については、表2 を参照してください。

表2. EEPROM 書込み関数の説明 – write_eeprom(uint16_t addr_eeprom, uint8_t data_eeprom)1
パラメータ 説明 戻り値
addr_eeprom データが書き込まれるEEPROM 空間内の論理アドレス。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。
data_eeprom EEPROM 空間のaddr_eeprom によってポイントされる場所に書き込まれるデータ。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。
1 この関数は、EEPROMからデータを読み出します。

EEPROM の読出し

EEPROM の読出し動作のフローチャートを図4 に示します。EEPROMの読出し動作手順は以下のとおりです。

  1. read_eeprom(addr)関数を呼び出して、アドレス・ロケーションに保存されているEEPROM値を読み出します。
  2. アプリケーション・コードからのEEPROM読出し要求において、ソフトウェアは、最新のデータで構成される現在のセクタを最初に決めます。フラッシュ・アドレスは、EEPROMアドレスと現在のセクタ開始アドレスでわかります。
  3. 得られたフラッシュ・アドレスを使ってread_flash()関数を呼び出し、読出しコマンドを実行します。
  4. そのフラッシュ・アドレスから取得した64 ビット幅のデータを処理します。その後、このアドレスのビットはマスクされ右シフトされて、アプリケーション・コードに提供されます。
図4. EEPROM の読出し動作
図4. EEPROM の読出し動作

read_eeprom(uint16_t addr_eeprom)関数の詳細については、表3 を参照してください。

表3. EEPROM 読出し関数の説明 – read_eeprom(uint16_t addr_eeprom)1
パラメータ 説明 戻り値
addr_eeprom データが読み出されるEEPROM 空間内の論理アドレス。 値。アプリケーション・コードに8 ビット・データが返されます。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。
1 この関数は、EEPROMからデータを読み出します。

EEPROM の消去

EEPROM の消去動作のフローチャートを図5 に示します。EEPROMの消去動作は以下のとおりです。

  1. erase_eeprom()関数を呼び出して、フラッシュ・メモリに割り当てられたEEPROM空間全体を消去します。
図5. EEPROM 消去動作
図5. EEPROM 消去動作

フラッシュ・メモリ内の、EEPROM エミュレーション専用に割り当てられた全てのページが消去されます。このため、アプリケーション・コード内でこの操作を使用するときは注意が必要です。

erase_eeprom()関数の詳細については、表4 を参照してください。

表4. EEPROM 消去関数の説明 – erase_eeprom()1
パラメータ 戻り値
Not applicable エラーなし。消去完了。
エラー。フラッシュ・コントローラがビジー状態で消去を実行できません。
1 この関数はEEPROMメモリ空間を消去します。この関数を呼び出すと、全てのデータが失われます。

フラッシュ

ADuCM3027/ADuCM3029 プロセッサは128kB または256kB の組込みフラッシュ・メモリを内蔵しており、フラッシュ・コントローラを介してアクセスすることができます。組込みフラッシュ・メモリは72 ビット幅のデータ・バスを備えており、1 回のアクセスで、2 個の32 ビット・ワードのデータと、それに対応する8 ビットのECC バイトを送ることができます。メモリはそれぞれ2kB ずつのページで構成され、更に256 バイトがECC用に予約されています。デフォルトでは、ECC はADuCM3027/ADuCM3029 のフラッシュのユーザ・スペース全域で有効化されています。フラッシュのあるロケーションへの書込みによって、そのロケーションのデータとECC バイトが更新されます。フラッシュ・メモリでは、ビット値をロジック0 からロジック1 に変更できるのは消去手順のみであるため、1 回の書込み動作しか許可されません。このため、ECC バイトは1 回だけ更新されます。消去手順を経ずに同じロケーションに書き込むと、ECC エラーが発生します。

フラッシュへの書込み

フラッシュ・メモリは、消去時には各ビットを1 に設定し、データ書込み(プログラム)時には選択的にビットを0 にクリアすることで動作します。書込み動作でビットを0 から1 に設定することはできません。このため、一般的な書込みアクセスの際は、予め消去動作を行う必要があります。

キーホール書込みは、ユーザ・コードがターゲット・アドレスとデータ値を使ってメモリ・マップ・レジスタをプログラムし、その後にバックグラウンドで書込み動作を行うよう、フラッシュ・コントローラにコマンドを送る間接的な書込み動作です。フラッシュ・コントローラは、キーホール書込みによるフラッシュ・メモリへの書込みアクセスだけをサポートしています。書込みアクセスに関するこの制約により、フラッシュ・コントローラによる書込みは、確実に、アトミックなダブル・ワード(64 ビット)動作として行われます。

EEPROM のデータを使って生成されるLSB とMSB のデータ・パケットは、キーホール・データ・レジスタに送られます。書込みコマンドがアサートされると、フラッシュ・コントローラは、所定のフラッシュ・アドレスへの64 ビットのデュアル・ワード書込みを開始します。

ワード(32 ビット)、ハーフ・ワード(16 ビット)、バイト(8 ビット)での書込みはサポートされていません。

write_flash(uint32_t addr, uint32_t lower_data, uint32_t upper_data)関数の詳細については、表5 を参照してください。

表5. フラッシュ書込み関数の説明 – write_flash(uint32_t addr, uint32_t lower_data, uint32_t upper_data)1
パラメータ 説明 戻り値
addr EEPROM エミュレーション用に割り当てられたフラッシュ・メモリ空間内のアドレス。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。該当せず。
lower_data ダブル・ワードの下位32 ビット。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。
該当せず。
upper_data ダブル・ワードの上位32 ビット。 エラーなし。書込み完了。
エラー。指定したアドレスは使用可能なEEPROM メモリ空間の外にあります。
該当せず。
1 この関数は、変換されたEEPROMアドレスとデータをwrite_eeprom()関数から受信して、フラッシュ・コントローラに書込みコマンドを送出します。

フラッシュの消去

EEPROM への書込み中にページが変更されると、erase_flash(page)関数を呼び出すことによって、前ページ上でページ消去コマンドがアサートされます。ページ消去の前には、EEPROM への書込みのセクションで説明したように、データの移動が行われます。

erase_flash(uint8_t PAGE)関数の詳細については、表6 を参照してください。

表6.フラッシュ消去関数の説明 – erase_flash(uint8_t PAGE)1
パラメータ 説明 戻り値
Page 割り当てられたフラッシュ・メモリ空間のページ番号。 エラーなし。ページ単位消去完了。
エラー。指定したページ値は、割り当てられたフラッシュ・メモリ空間の外にあります。
1 この関数は、割り当てられたフラッシュ・メモリ空間内にあるページの内容をすべて消去します。

フラッシュの読出し

フラッシュ・メモリは、自動初期化プロセス後にのみ読み出すことができます。フラッシュ・メモリを読み出すと、64 ビットのダブル・ワード・データが返されます。

フラッシュ・アドレス情報はフラッシュ・コントローラに提供され、それによって読出しデータが返されます。このデータが更にEEPROMインターフェースで処理され、EEPROM値が得られます。

read_flash(uint32_t addr)関数の詳細については、表7 を参照してください。

表7.フラッシュ読出し関数の説明 – read_flash(uint32_t addr)1
パラメータ 説明 戻り値
addr EEPROM エミュレーション用に割り当てられたフラッシュ・メモリ空間内のアドレス。 データの読出し。目的のアドレスで取得されたデータが関数に戻ります。
エラー。変換したアドレスは、割り当てられたフラッシュ・メモリ空間の外にあります。
1 この関数は、変換されたEEPROMアドレスをread_eeprom()関数から受信して、フラッシュ・コントローラへ読出しコマンドを送出します。

制約事項

実際のEEPROM では、1 つのロケーションが更新されると、消去サイクルは1 サイクルだけカウントされ、そのアドレスに書込みを行いますが、他のロケーションは変更しません。

このエミュレートされたEEPROM では、1 つのロケーションを更新すると現在のセクタから隣のセクタへデータが移動されて、書込みサイクルの数だけEEPROM サイズが消費されます。したがって、あるロケーションの更新の都度、データが次のセクタに移動し、そのセクタが次ページにある場合はページ消去が実行されることになります。この動作によって、フラッシュ・メモリの有効書換え回数は減少します。

これらの制約に対処するには、以下の点に留意します。

  • エミュレートするEEPROMのサイズを選択する際は注意が必要です。EEPROMサイズを小さくするとデータ移動時の書込みサイクルが短くなり、そのため、フラッシュ・メモリの書換え回数が間接的に増加します。
  • 2 つ目は、EEPROMへの不要な書込みを避けることです。それによって、フラッシュ・メモリの有効書換え回数が増加します。例えば、システムが書込み命令を出す必要があるのは、電源異常シーケンス時のみです。通常動作時のデータ保存には、RAMバッファを使用することができます。エミュレートされたEEPROMへの不要な書込みには、ソフトウェアによって処理できるものもあります。例えば、書込みデータが0xFF で、書込み先ロケーションの現在のデータが0xFFである場合、フラッシュ・メモリへの書込みは行われません。

まとめ

このアプリケーション・ノートの目的は、ADuCM3027/ADuCM3029 を使って、EEPROMとフラッシュ・メモリの物理的な差を埋めることです。このエミュレートされたEEPROMは実際のEEPROM同様に機能し、シリコン面積、入出力バス・リソース、製造コストなどに関する課題を解決します。

このアプリケーション・ソフトウェアでは、EEPROM エミュレーション用に2 ページ分のフラッシュ・ページが予約されているため、このアプリケーション・ノートでは8 バイト~2kB(1 ページ)という大きなEEPROM サイズがユーザに提供されます。ソフトウェアを4 フラッシュ・ページ分に拡張すれば、最大EEPROMサイズは4kB となり、ワード長は8~64 ビットに設定可能です。

エミュレートするEEPROM のサイズとフラッシュ・メモリの書き換え回数はトレードオフの関係にあるので、ハードウェアの効率を向上させるには、適切なサイズを選択する必要があります。この他、ADuCM3027/ADuCM3029 のフラッシュ・デバイスへの不要な書込みの一部をソフトウェアで処理することで、有効書換え回数は増加します。