トップ 新規 編集 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

Getting Started Notes - SRAM上変数

最終更新時間:2007年08月26日 13時12分53秒

SRAM上の変数

 概要

※要は、C言語で普通に宣言された変数です。置き場所は通常はSRAM上ですが、一時的にレジスタ上に置かれることもあります。

 WinAVRにて特に属性を定めずに定義された変数はコンパイラによってマイクロコントローラのSRAMメモリ上に置かれます。
メモリーはI/Oレジスタを介することなく(というかIOレジスタと同様に)直接アクセス可能です。これにより他のメモリ(eepromなど)より高速に読み書きでき、操作関数も不要です。

よく使われる整数データ型はインクルードファイル <inttypes.h>にまとめられています。ファイル<avr/io.h>が読み込まれると、<avr/sfr-defs.h>経由でデータタイプ定義の<inttypes.h>が自動的にインクルードされます。

 定数はキーワード"const"により収納されます。この変数??は読み込み専用の状態にあり、変更されることはありません。

<inttypes.h>による定義済み型

整数型名 変数サイズ 表現できる範囲
int8_t   1 -128〜127
uint8_t   1 0〜255
int16_t   2 -32768〜32767
uint16_t   2 0〜65535
int32_t   4 -2147483648〜2147483647
uint32_t   4 0〜4294967295
int64_t   8 -9.22*10^18〜9.22*10^18
uint64_t   8 0〜1.844*10^19

 宣言

変数

要するに普通のC言語の変数宣言です。

uint_8 val = 8;  // SRAM上変数作成
val = 10;        // 代入

SRAM上定数の生成

const uint8_t october = 10;  // SRAM上定数

定数宣言は、C言語上octoberの値を代入などで変更できないことを除けば、初期値付き変数確保と違いはありません。この定数値はFLASH-ROM上ではなくSRAM上に置かれることに注意してください。たくさんの定数を確保すると使用可能なSRAMが無駄に圧迫されます。常に他の定数確保方法が可能でないか考慮してください。→プログラムメモリ上の定数 参照

レジスタ上変数

register uint8_t regval asm("r2");

この命令により、AVRの汎用レジスタR2上に変数が確保されます。これは頻繁に参照される変数、割り込み内などで特に高速に処理される必要がある変数に特に有用です。

register uint16_t regval_w asm("r2");

このようにするとR2:R3にワード変数が確保されます。

※レジスタ上変数は大変高速に・小さいコードで読み書きできますが、レジスタの数に限りがあるため多くの変数は定義できません。せいぜい5,6バイト程度が限度と考えた方がよさそうです。

最適化

(SRAM上)変数を利用する場合、AVRではまずld/ldd/lds命令で変数を汎用レジスタに持ってきて、処理を行った後st/std/sts命令でSRAMに保存するような動作をします。
本棚から書類を取って、机の上で使って最後に本棚に戻すようなものです。

avrgccは最適化機能を持っています。ある変数に対する処理が連続して行われる場合は、一度汎用レジスタに持ってきたデータをいちいちSRAMに返さずに、レジスタ上に置いたまま操作して、最後にSRAMに保存するようなコードを作ることができます。
同じ書類を何度か使う場合は使い終わるまで書類を本棚に戻さないのに似ています。

また、値の代入→変数の使用というパターンを繰り返す場合は、最後にSRAMに保存する必要もないので(次に使用するときは値の代入から始まるので保存した値が使われない)、これははじめからSRAMを使用せずレジスタしか使われないコードを作ることができます。
棚に戻す必要がないなら机の上の使い捨てのメモ帳を使ってしまえ、という感じですね。

どちらの場合でも、その変数を使用する処理の間に他の変数を使う処理がたくさんはいると汎用レジスタが不足してSRAMに変数値を書き戻さざるを得なくなります。逆に1つの変数を使う処理を一カ所にまとめると、うまく汎用レジスタを使って最適化してくれるケースが増えます。

ローカル変数は、スタックポインタ位置から相対参照命令(ld/stなど)で参照できるため、lds/sts命令で参照されるグローバル変数よりコードサイズ、実行速度共に有利になります。
「棚の何列目の左から何番目」と指定するよりも、「さっき使った書類の隣」という指定の方がアクセスが速い、っていった感じでしょうか。