2012年5月15日火曜日

ARMの変数型名

ARMは環境依存の変数型を無くすために普通のCとは違う名前で型が宣言されてます
ってことで その一覧です


通常の宣言 CMSISでの宣言
-
signed long - int32_t
- signed short - int16_t
- signed char - int18_t
- signed long const const int32_t
- signed short const const int16_t
- signed char const const int8_t
volatile signed long - __O int32_t
__IO int32_t
volatile signed short - __O int16_t
__IO int16_t
volatile signed char - __O int8_t
__IO int8_t
volatile signed long const __I int32_t
volatile signed short const __I int 16_t
volatile signed char const __I int8_t
- unsigned long - uint32_t
- unsigned short - uint16_t
- unsigned char - uint8_t
- unsigned long const const uint32_t
- unsigned short const const uint16_t
- unsigned char const const uint8_t
volatile unsigned long - __O uint32_t
__IO uint32_t
volatile unsigned short - __O uint16_t
__IO uint16_t
volatile unsigned char - __O uint8_t
__IO uint8_t
volatile unsigned long const __I uint32_t
volatile unsigned short const __I uint16_t
volatile unsigned char const __I uint8_t

↑の表のように 用途によって 色々と決まりごとがあるみたいです
(excelからコピペしただけなので見づらいですがご了承ください)

もちろん普通のCのようにintとかcharとかboolも可能ですが
この表に従ったほうが環境依存が減るので楽なんだそうです
覚えるのめんどくせーよ…

で ちょっと解説
かなり憶測を含んでるので間違ってたらごめんなさい
まず型の大きさですが
これはint+ビット数で決まります
コンパイラ依存のビットサイズじゃないので
移植が楽だけではなく 読むときにも楽なんだそうです

signed/unsignedですが まぁこれは説明しなくてもわかりますよね
符号あり/なしの区別です
符号ありはint 符号なしはuintです
constは定数か否かみたいな意味合いもありますが
組み込みの場合はRAMかROMかという違いもあります
でもまぁあまり意識することはないと思います

で 問題なのがvolatileっていう国の名前みたいなモノ
これはコンパイラの最適化を無効化するみたいな意味があります
例えば
uint8_t flag = 1;
while(flag) { ... }
というコードがあったて ブロックの中でflagを書き換えていない場合
コンパイラは
while(1) { ... }
と書き換えます

これは「どーせ値が変更されることはないんだから判定するだけムダ」という理由によるものですが
もしかしたらこのflagは割り込みで変更される可能性があるかもしれません
例えばシリアルの送信完了でRESETされる場合
本来は送信が終了されるまで待つだけのはずなのに
実際は無限ループに陥ってしまいます

これを回避するためにvolatileをつけることにより
「この変数は外部から変更されるので強い最適化はしないように」
ということになります

volatileについてはこのページがわかりやすいです

__IOだけでなく__Oも有るのは
コード中から間違って書き換えないように ということだと思います
が __Oを使う用途というのはあまり思いつかない(無いわけではない)


とりあえず こんなところですが
今まではARMでも普通にintとかcharとか使ってたけど
これから少しずつint32_tみたいな書き方に移行していこうかなぁ と 思ったり

0 件のコメント:

コメントを投稿