SRAM節約:定数をプログラムメモリーに

avr-gccではconstがついている変数でも一度SRAMに値をコピーしてから実行します。数byte程度ならば問題ありませんが巨大な文字列テーブルを確保する場合などには結構SRAMを圧迫します。しかもこれらの領域は使用後に解放されません。デバッグ用文字列を大量に用意していると、いつの間にやらデバッグ用文字列の方が多くのSRAMを使っているということもたまにあります…。

しかし、定数ならば一々SRAMにコピーしなくてもプログラムメモリーから直接読んでしまっても問題ないはずです。avrlicにはそのための関数が用意されています。

まずは定数をプログラムメモリーに置く方法ですが、<avr/pgmspace.h>をインクルードして、変数宣言の際に変数名の後ろにPROGMEMをつけるだけです。このとき初期化も一緒に行ってください。また、組み込み型はすでにtypedefされているものもあるのでそれを使うのもいいでしょう。ほかにも文字列を扱う場合にはPSTRやPGM_Pをつかうといいでしょう。(こちらはマクロで定義)

次にそれを読み出す方法ですが、プログラムメモリーに保存された定数には普通の方法ではアクセスできないので、特別な関数(実体は<avr/pgmspace.h>で定義されているマクロ)を使います。pgm_read_byte(), pgm_read_word(), pgm_read_dword()です。どれも、プログラムメモリーのアドレスを引数に取り、それぞれ、uint8_t, uint16_t, uint32_tの値を返します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です