STM32F7 FLASH(フラッシュメモリ)

前回から時間が空いてしまったが引き続きSTM32F7の機能について記述していく。今回はフラッシュメモリについて。以下にマニュアルと書かれているのはリファレンスマニュアル(RM0410 Rev4)のことを指している。

バンクのモード

STM32F7のフラッシュメモリには以下の2つのモードがあり、マイコンが起動する際のOPTCRレジスタのnBANKビットの状態によってどのモードになるかが決まる。
・シングルバンクモード:nBANKビット = 1の状態で起動
・デュアルバンクモード:nBANKビット = 0の状態で起動

モードによってフラッシュメモリへのアクセスビット長が異なる。
シングルバンクモード:256ビット
デュアルバンクモード:128ビット

デュアルバンクモードではフラッシュへ書き込み中にフラッシュから読み込みをすることが可能。加えてデュアルブートモードを有効にできる。

シングルバンクモードからデュアルバンクモードへの切り替え、またはその逆の切り替えの手順がマニュアルP94に書かれている。
切り替えるとフラッシュメモリの内容が書き換わってしまうため、切り替え処理はRAM上で実行しなければならない。

セクター

それぞれのモードにおけるメモリのセクターは以下のようになる。

ここで、インフォメーションブロックのシステムメモリーにはST社のブートローダーが記録されており、書き換えることはできない。

フラッシュメモリの削除

フラッシュメモリの削除はセクター単位、あるいはバンク単位でのみ可能。
従ってシングルバンクモードではセクター単位での削除かフラッシュメモリ全削除かの2択となる。
デュアルバンクモードではセクター単位、バンク1の全削除、バンク2の全削除の3択となる。
どの削除方法でもインフォメーションブロックの内容は削除されない。

フラッシュメモリへのアクセス

フラッシュメモリのインターフェース

フラッシュメモリのインターフェースは3つある。

64ビット ITCMインターフェース

命令とデータのやり取りに使われる。このインターフェースを使ったフラッシュメモリへの書き込みはできない。このインターフェースではARTが使える。

64ビット AHBインターフェース

命令とデータのやり取りに使われる。DMAはこのインターフェースを通して行われる。

32ビット AHBレジスタインターフェース

フラッシュメモリのコントロールレジスタ、ステータスレジスタのアクセスに使われる。

ウェイト時間

フラッシュメモリの動作速度に対してCPUの動作速度が速いため、読み込みの際にはウェイト時間(遅延時間)を入れる必要がある。具体的な遅延時間やその設定方法はマニュアルP91を参照。

プリフェッチ

最初に書いたようにシングルバンクモードとデュアルバンクモードではフラッシュメモリへのアクセスビット長が異なり、これによって一度に読み出せる命令の数も変化する。

リフェッチを有効に設定しておくと上の表のように一度に複数の命令を読み取り、フラッシュアクセスの遅延を抑えることができる。ただし、命令はフラッシュから連続して読み出してプリフェッチするので分岐命令などにより連続しない命令に飛ぶ必要が出たときは効果が得られない。

3.3VでSTM32F7マイコンを216MHzで動作させると7クロックの遅延が必要になるが、シングルバンクモードでは一度のアクセスで32ビット命令を8個読み出せるため遅延の影響はほぼ無いと思われる。
一方デュアルバンクモードでは一度のアクセスで32ビット命令を4つしか読み出せないので、4クロック命令を実行した後は3クロック待機しないといけない。
しかし以下のST社の資料のP24によるとシングルバンクモードでもデュアルバンクモードでもプリフェッチとARTを有効にしていれば実行速度に差は無いと書かれている。この理由がまだ分かっていない。

なお、プリフェッチとARTは別物であるため混同しないように注意が必要。
ちなみにフラッシュメモリの設定を変えたりするときなどにARTのキャッシュをクリアすることが推奨されているが、ARTのキャッシュはARTが無効の時にのみクリアできる。

フラッシュメモリへの書き込み

フラッシュメモリに書き込んでいる最中はフラッシュメモリに対するリード、削除アクセスはできない。

フラッシュメモリは初期状態が0xFFで、削除すると0xFFになる。つまり初期状態ではビットは全て1になっているので、1の状態を0にしたい場合は書き込みをするだけでよい。
逆に0の状態を1にする場合には一旦削除して初期状態(1の状態)に戻してから改めて書き込みをする必要がある。
フラッシュメモリの削除シーケンスについてマニュアル P95に書かれている。

FLASH_KEYRレジスタに特定の値を書き込むとロックが解除され、FLASH_CRレジスタの書き換えができるようになる。ロック解除シーケンスを間違えると次回のリセットまでFLASH_CRレジスタはロックされる。FLASH_CRレジスタのLOCKビットに1を書き込むと再度ロックされる。詳しくはマニュアルP93参照。

フラッシュメモリに書き込んでいる最中(FLASH_SRレジスタのBSYビットが1になっている最中)はFLASH_CRレジスタにアクセスできない。この時にアクセスするとFLASH_SRレジスタのBSYビットがクリアされるまでAHBバスがストールするとマニュアルには書かれているが、ストールが具体的にどういう状態でどんな問題が発生するのか私の知識では分からなかった。

フラッシュに書き込みを行うとき、電源電圧によって一度のアクセスで何バイト同時に書き込みできるか決まる。電源電圧が3.3Vのときは1回のアクセスで32バイトの書き込みができる。
Vppピン(BOOT0ピンと共用)に電源を供給することでさらに高速な書き込みが可能だが、これは工場で書き込みを行うときに使う機能のようだ。詳しくはマニュアルP93参照。

オプションバイト

オプションバイトとはSTM32CubeProgrammerでマイコンを接続して画面左側にあるOBというボタンを押すと出てくる項目を設定するための特殊なフラッシュメモリのことである。
FLASH_OPTCRレジスタとFLASH_OPTCR1レジスタを介して読み書きが可能。

FLASH_OPTKEYRレジスタに特定の値を書き込むとロックが解除され、FLASH_OPTCRレジスタとFLASH_OPTCR1レジスタの書き換えができるようになる。FLASH_OPTCRレジスタのOPTLOCKビットに1を書き込むと再度ロックされる。
FLASH_OPTCR、FLASH_OPTCR1レジスタへのリードアクセスはプロテクトを解除しなくても可能。

紛らわしいが、オプションバイトの内容=OPTCRレジスタ、およびOPTCR1レジスタの内容ではない。
OPTCRレジスタとOPTCR1レジスタの値はマイコンが起動したときにオプションバイトからロード(コピー)される。よってこのレジスタの値を変えても次回のリセットまで設定が反映されないので注意。
オプションバイトの実際の値は下記のアドレスから読むことができる。詳しくはマニュアルP99を参照。

オプションバイトの値を変更するためには
1.起動時にオプションバイトの値をFLASH_OPTCR、FLASH_OPTCR1レジスタへコピー(これは起動時に自動的に行われる)
2.FLASH_OPTCR、FLASH_OPTCR1レジスタの値を変更
3.FLASH_OPTCR、FLASH_OPTCR1レジスタの値をオプションバイトへ書き込み
という手順を踏む必要がある。詳しくはマニュアルP102を参照。

書き込み時の注意点

FLASH_OPTCR、FLASH_OPTCR1レジスタに値を書き込んだ後、FLASH_OPTCRレジスタのOPTSTRTビットをセットするとオプションバイトの書き換えが始まる。このときオプションバイトの内容は一旦全て削除され、その後に改めてOPTCR、OPTCR1レジスタの値が書き込まれる。

ST-Linkなどのデバッガを使ってデバッグ、書き込みを行うと一旦リセットがかかってから数百ミリ秒プログラムが走り、その後に再度リセットがかかって書き込みやデバッグが始まる。
この数百ミリ秒の間にオプションバイトを書き換える動作が実行されると本来はオプションバイトの全削除→新規書き込みとなるはずの動作が、全削除の時点で2回目のリセットがかかって止まってしまい、FLASH_OPTCRレジスタのRDPビットが0xFFの状態のままになってしまうことがある。こうなるとフラッシュメモリへのリードアクセスができなくなり、デバッガの接続ができなくなるので注意が必要だ。RDPビットについては次の項で説明する。
この場合にはSTM32CubeProgrammerからRDPビットを0xAAに戻してやれば再びデバッガの接続が可能になる。

RDP(リードプロテクションレベル)

リードプロテクションレベル(RDP)によってフラッシュメモリへのアクセスが制限される。アクセス制限にはレベル0からレベル2まである。

レベル0

アクセス制限なし。

レベル1

デバッガが接続された状態、あるいはRAMやインフォメーションブロックのシステムメモリーからブートした状態ではフラッシュメモリーとバックアップSRAMに対する読み込み、書き込み、削除のアクセスができない。
メインメモリーブロックのフラッシュメモリからブートした場合はフラッシュメモリとバックアップSRAMに対する読み込み、書き込み、削除のアクセスが可能。
ST-Linkなどを使ってRDPをレベル1の状態からレベル0に下げる場合、メインメモリーブロックの内容は全て削除される(0xFF状態に戻る)。
RDPを上げる場合(0→1、1→2、0→2)はメインメモリーブロックの中身は削除されない。

レベル2

レベル1の内容に加えてRAMやインフォメーションブロックのシステムメモリーからのブートが不可能になる。
JTAG、SWV、ETMなどの機能が使えなくなるため、デバッガなども接続できなくなる。
インフォメーションブロックのオプションバイトも書き換えが不可能になる。
メインメモリーブロックのフラッシュメモリーからブートした場合のみフラッシュメモリーとバックアップSRAMに対する読み込み、書き込み、削除のアクセスが可能。
一度レベル2に設定すると二度とレベル1、レベル0に戻すことはできない。

書き込み保護

FLASH_OPTCRレジスタのnWRPビットをクリアすることでメインメモリーブロックのフラッシュメモリに対して書き込み保護をかけることができる。
nWRPビットをセットするとフラッシュメモリへの書き込みが解除されるが、RPDがレベル1以上に設定されている場合はフラッシュメモリに書き込みできない。

デュアルバンクモードにおいてはセクター2つずつの単位でしか書込み保護をかけられない。

書込み保護された状態で書き込みを行おうとするとFLASH_SRレジスタのWRPERRビットがセットされる。どのような条件でWRPERRビットがセットされるかはマニュアルP105~106に詳しく書かれている。

OTP(ワンタイムプログラマブルバイト)

ワンタイムプログラマブルバイト(OTP)のメモリの構成は以下のようになっている。

LOCKブロックには0xFFか0x00のいずれかしか書き込んではならず、それ以外の値が書き込まれた場合は動作が保証されない。
OTPブロック0~15に対応するLOCKブロックのアドレスに0xFF(初期値)が書き込まれている間はOTPブロック0~15に書き込むことができる。
LOCKブロックに0x00が書き込まれると対応するOTPブロック0~15は二度と書き込めなくなる。