LoginSignup
6
4

More than 3 years have passed since last update.

STM32F4のバックアップSRAM

Posted at

STM32F4には4KiBのバックアップSRAM(BKPSRAM)が搭載されている。VDD or VBATから電力を受けて、「バックアップバッテリが接続されていればEEPROMと同様に扱える」メモリ。
RTCにもバックアップレジスタが実装されているが、こちらは20ワード(80バイト)しか無い。その代わりにタンパ検出(筐体の分解等を検出してデータを破棄する機能)がついている。
大きなデータはバックアップSRAM、小さなデータ(あるいはバックアップSRAMの暗号鍵)はRTCレジスタ、みたいな使い分け?


アドレスは0x40024000だが、BKPSRAM_BASEマクロが定義されているので、これを使うと便利。

BKPSRAMにアクセスするにはいくつかの手順が必要になる。読み出しには、電源コントローラ(PWR)の有効化、BKPSRAMインターフェースの有効化、が必要。書き込みにはライトプロテクトの解除も必要。

電源コントローラの有効化は__HAL_RCC_PWR_CLK_ENABLE();で行えるが、CubeMXでコードを生成するとSystemClock_Configの中で呼ばれているので、あまり気にする必要はないはず。

インターフェースの有効化には__HAL_RCC_BKPSRAM_CLK_ENABLE();を、解除には__HAL_RCC_BKPSRAM_CLK_DISABLE();を呼ぶ。
このインターフェースはマクロ名の通りSRAMインターフェースのクロックを有効化/無効化するもの。有効化しておかないと有効な値を読み取れなくなる。ただし、インターフェースが無効な状態で読み出すと、最後に読みだしたワードに含まれるバイトが読み出される仕様らしい。ゼロ埋めとかが出てくるわけじゃないのでデバッグ中は注意。なぜかうまく動かない、というときはクロック周りを疑うべし(って、これはARM全般に言えるか)。

書き込み時はインターフェースに加え、プロテクト解除が必要。プロテクト解除はHAL_PWR_EnableBkUpAccess();を、プロテクト有効化にはHAL_PWR_DisableBkUpAccess();を呼ぶ。アクセス時のEna/Disはインターフェースと逆なので注意。

アクセス時は、uint8_t *const bkpsram = reinterpret_cast<uint8_t *>(BKPSRAM_BASE);のようにポインタを宣言してやれば、そのままprintf("%02hhX\n", bkpsram[10]);としてみたり、bkpsram[4095] = 0xAA;という感じで使える。もちろん、好きな構造体を経由してもいい。

バックアップSRAMは、電源がなくなるとランダムなデータが入るらしい。RAMの中身が有効なデータかは自分で判断する必要がある。例えばSTM32にはCRC計算機が入っているので、BKPSRAMのCRCをRTCバックアップレジスタに入れておいて、BKPSRAM書き込み時にはCRCも計算し、読み出し時はCRCが一致しなければエラーとして扱う、というような挙動が考えられる(もちろんCRC自体をBKPSRAMに入れてもいい)。CRCが過剰であればチェックサムを使うことも考えられる。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4