組込みソフトウェアコーディングTips

volatile 指定

H/W のレジスタなど、ソースコード上ではいじらなくても値が変化する可能性のある変数があります。そのような変数は、volatile 指定をしておく必要があります。

volatile 指定をしないと、コンパイラの最適化により、最初の値評価以外のコードが消されてしまう可能性があります。その結果、絶対に抜けることのない無限ループとなってしまいます。

例として、以下のようなコードは、ソースコード上 while ループ内で timer_reg と expired の値が変化することはないので、コンパイラは無駄な処理と判断して削除します。

しかし、実際には H/W が timer_reg の値を更新していくので、while ループを回すことに意味があります。そこで、volatile 指定を行い、コンパイラにそのことを教えてあげます。

long* timer_reg;
long expired = 1000;

while (*timer_reg != expired) {}

組込みソフトウェアのコーディングで、レジスタ変数と while ループを使う場合ば、頭の片隅に入れておくと良いです。

Cache 操作

メモリアクセスの高速化のために、CPU などはキャッシュを備えています。全てのアクセスがキャッシュ経由で行なわれるのなら、あまり意識はしなくて良いのですが、キャッシュを経由せずに直接メモリ本体にアクセスする H/W もあります。その際に、キャッシュ上のデータと、メモリ本体にあるデータが食い違う可能性があります。

キャッシュ上のデータをメモリ本体に反映しているか。CPU で操作したあと、そのデータを別の領域へ DMA コントローラでコピーする場合、事前にキャッシュ上のデータをメモリ本体へ Write Back しておく必要があります。

キャッシュ上のデータがメモリ本体の内容を破壊しないか。DMA コントローラでコピーした先の領域に対応するキャッシュデータがある場合、せっかくコピーしたデータが、古いキャッシュデータで上書きされてしまいます。それを回避するために、事前にキャッシュ上のデータを無効化しておく必要があります。

アラインメント

各 H/W によって、メモリアクセスで利用できるアラインメントが異なります。その制約に沿わないアドレスを渡すと、動作は不正となり、デバッグに苦労します。

また、構造体を定義する時も、CPU のアラインメントを意識して、パディングを考慮しておきます。

4byte, 32byte, 4KB など、アラインメントは、H/W によって様々です。


履歴


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS