スポンサーサイト 

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

レジスタへのアクセス表現 

組込みやドライバ関連のコードを書いている人ならば避けて通れないのがレジスタアクセスです。 いくつか都合の良い妄想が入り込んでいますがレジスタへのアクセスする際のコードの書き方を並べてみました。

 

アドレス0x43210000にFIFO_STATUSという32bitレジスタが割り当てられていてbit0はFIFOがEmptyであるかどうかを示すビットであったとします。

if ((*(volatile unsigned long *)0x43210000) & 1) != 0) {

}


さすがにこのように(業務で)書いている人はいないかと思います。チェックアウトしたコードに上記のような書き方がされていたら、 がっかりする人がほとんどではないでしょうか。

#define REG_FIFO_STATUS 0x43210000
if ((*(volatile unsigned long *)REG_FIFO_STATUS) & 1) != 0) {

}


こうなってくると普通っぽく見えてきます。 FIFO_STATUSというレジスタが複数個所で使用されることを考慮するのとEmptyビットに対する処理であることを明確にするために

#define REG_FIFO_STATUS ((volatile unsigned long *)0x43210000)
#define FIFO_STATUS_EMPTY 0x00000001
if ((*REG_FIFO_STATUS & FIFO_STATUS_EMPTY) != 0) {

}


こうなってくるとどこでも見かけるコードです。ただこの場合、

#define REG_FIFO_STATUS ((volatile unsigned long *)0x43210000)
#define FIFO_STATUS_EMPTY 0x00000001

// FIFOがEmptyの場合
if ((*REG_FIFO_STATUS & FIFO_STATUS_EMPTY) != 0) {

}


のようにコメントを付けておかないとレジスタ仕様書の内容を知らなければEmptyでない場合の処理なのかそうでないのかがわかりにくくなります。 そこでこういうこういう書き方も考えられます。

typedef volatile union {
    unsigned long value;
    struct reg_fifo_status_field {
        unsigned long empty:1;
        unsigned long oe:1; // overflow error flag
        …
    } b;
} reg_fifo_status_type;
#define FIFO_STATUS_NOT_EMPTY 0
#define FIFO_STATUS_EMPTY 1
#define FIFO_STATUS_OVERFLOW 1

#define REG_FIFO_STATUS ((reg_fifo_status_type *)0x43210000)
if (REG_FIFO_STATUS->b.empty == FIFO_STATUS_EMPTY)

}


これならばコメントを書かなくてもどちらの場合の処理かわかります。 ビットフィールドを使用することに対する是非はとりあえずここでは考えていません。 相手がハードウェアですからリードすると消えてしまうビットや同時に複数のビットに書き込まなければならないビットがあったりします。 処理速度やコードサイズの制限さえ許せば

#define FIFO_STAUTS_SET_EMPTY 1
#define FIFO_STATUS_CLR_OVERFLOW 1

reg_fifo_status_type reg_status;

reg_status = REG_FIFO_STATUS->value;
reg_status.b.empty = FIFO_STATUS_SET_EMPTY;
reg_status.b.oe = FIFO_STATUS_CLR_OVERFLOW;
REG_FIFO_STATUS->value = reg_status.value;


と書くことで実現できます。


どのような表現を使用するかはケースバイケースで選択すべきだと思いますが、 多くの表現方法を覚えておくことは損することにはならないでしょう。


コメント

コメントの投稿















管理者にだけ表示を許可する

トラックバック

この記事のトラックバックURL
http://ochoo.blog48.fc2.com/tb.php/34-e522e5aa

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。