プログラミング

ハードウェア制御のためインラインアセンブラではなく組込み関数を活用

<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >ハードウェア制御のためインラインアセンブラではなく組込み関数を活用</span>
 

組込みシステムの、ハードウェア制御の直接かかわる部分では、低レベルのプログラミングインタフェース(インラインアセンブラと組込み関数)が必要です。C言語は、ハードウェア制御に近い記述が可能で、組込みシステムの開発に適した言語です。このため、使用するデバイスの周辺機能を比較的容易に制御することが可能です。

しかし、C言語のみでは不十分なことがあり、その場合はC言語とアセンブリ言語の両方を混在させて記述する必要があります。

int foo() 
{ ...
InitADC();
InitTimer();

/* Enable interrupts */
asm("CPSIE i");

while(1){
CollectData();

asm("NOP");
CalcData();
...
}
}

インラインアセンブラはCまたはC++のソースコードに対して、アセンブリ言語を記述するための仕組みです。ハードウェアリソースに直接アクセスしたり、高いリアルタイム性が求められる実装をしなければならない場合に、便利です。

インラインアセンブラの記述は関数と同様に、引数を取ることができ、また戻り値を持つことができ、さらにC言語上のシンボルを参照することができます。インラインアセンブラでは、clobberリスト(命令の実行により暗黙に上書きされる可能性があるレジスタやメモリを示すリスト)を宣言することが可能です。

オペランドとclobberリストがない場合、インラインアセンブラはC言語とのインタフェースがなくなります。このことは、ソースコードを脆弱にし、将来、保守上の問題となるかもしれません。インラインアセンブラを使うことの制限は、コンパイラの各種最適化がインラインアセンブラの影響を考慮できなくなることで、最適化が全くかからなくなることもありえます。そのため、インラインアセンブラは、可能な限り使用を控え、もし使う場合は独立した関数やモジュール内に限定すべきです。

ハードウェア制御に対するもう少し良いアプローチは、インラインアセンブラの代わりに組込み関数を使用することです。IAR Embedded Workbenchでは、インラインアセンブラを使用することなく、低レベルのプロセッサの処理を直接実行する組込み関数を提供します。特に、時間的な制約が厳しい処理を実装する際に便利です。

組込み関数は通常の関数に見た目は似ています。組込み関数は、コンパイルされると、1つ以上の命令に置き換わります。関数名の先頭にある2つのアンダースコア(__)が目印です。

アプリケーションの中で組込み関数を使うために、ヘッダファイルintrinsics.hのインクルードが必要です。

#include "intrinsics.h"

int foo()
{ ...
InitADC();
InitTimer();

/* Intrinsic function to enable interrupts */
__enable_interrupt();

while(1){
CollectData();

/* Intrinsic function for NOP */
__no_operation();
CalcData();
...
}
}

コンパイラのマニュアルには、組込み関数の一覧があります。一覧には各関数の説明がありますので、参考にしてみてください。