シミュレーションでのスタブ関数
-
03-07-2019 - |
質問
一部の外部ハードウェアに依存する組み込みCプロジェクトに取り組んでいます。これらの部分にアクセスするコードをスタブ化したいので、ハードウェアを使用せずにシステムをシミュレートできます。今まではいくつかのマクロを使用していましたが、これにより生産コードを少し変更せざるを得なくなりました。これは避けたいと思います。
例:
stub.h
#ifdef _STUB_HW
#define STUB_HW(name) Stub_##name
#else /*_STUB_HW*/
#define STUB_HW(name) name
#endif /*_STUB_HW*/
my_hw.c
WORD STUB_HW(clear_RX_TX)()
{ /* clear my rx/tx buffer on target HW */ }
test_my_hw.c
#ifdef _STUB_HW
WORD clear_RX_TX()
{ /* simulate clear rx/tx buffer on target HW */ }
このコードを使用すると、プリプロセッサタグ _STUB_HW
でスタブをオン/オフにできます。
私のprodコードを変更することなく、そして多くのifdefを避けることなくこれを達成する方法はありますか。また、回避できる場合は、同じファイルにprodコードとテストコードを混在させません。実稼働コードから可能な限り排除できる限り、テストコードがどのように見えるかは気にしません。
編集:
ファイル全体を置換せずに関数を選択/名前変更することが可能であれば、便利です。たとえば、 nRF _ ##
で始まり、新しい名前を付け、次に nRF _ ##
に nRF _ ##
を挿入します(可能な場合)。
解決
まったく同じ関数名を含む2つのファイルActualDriver.cとStubDriver.cを作成します。実動コードを異なるオブジェクトにリンクする2つのビルドを作成することにより、名前の競合は発生しません。このように、本番コードにはテストコードも条件コードも含まれていません。
他のヒント
Gerhardが言ったように、共通のヘッダーファイル" driver.h"を使用します実際の機能とスタブ機能を含む個別のハードウェア層実装ファイル。
日食では、2つのターゲットがあり、「ビルドから除外」します。使用されないdriver.cファイル。適切なものがビルドに含まれていることを確認します。その後、Eclipseはビルド時にメイクファイルを生成します。
指摘するもう1つの問題は、固定サイズの整数を定義して、コードがオーバーフローの観点から同じように動作するようにすることです。 (あなたのコードサンプルから、私はあなたがそれをしているのを見ることができます。)
上記に同意します。これに対する標準的な解決策は、「ドライバー」である不透明で抽象化された関数呼び出しのセットを定義することです。 hwに追加し、メインプログラムで呼び出します。次に、hw用とsw用の2つの異なるドライバー実装を提供します。 swバリアントは、適切な方法でhwのIO効果をシミュレートします。
目標がより低いレベルにある場合、つまり、機能全体ではなく各ハードウェアアクセスをシミュレートするコードを記述する場合、少し面倒になる可能性があることに注意してください。しかし、ここでは、異なる「メモリへの書き込み」および" read_from_memory"関数(またはターゲットの速度が重要な場合はマクロ)を定義できます。
どちらの場合も、関数の名前を変更する必要はありません。2つの異なるバッチファイル、メイクファイル、またはIDEビルドターゲット(使用しているツールに応じて)だけが必要です。
最後に、多くの場合、より優れた技術的解決策は、 Qemuなどの本格的なターゲットシステムシミュレータを使用することです。 、 Simics 、 SystemC 、 CoWare 、 VaST など。これにより、常に同じコードを実行でき、代わりに、ソフトウェアの観点から実際のハードウェアのように機能するハードウェアのモデルを構築できます。先行投資はかなり大きくなりますが、多くのプロジェクトでは努力する価値があります。基本的に、ターゲットとホストに異なるビルドを持つという厄介な問題を取り除き、デプロイビルドオプションでクロスコンパイラを常に使用するようにします。多くの組み込みコンパイラスイートには、このような基本的なシミュレーション機能が組み込まれていることに注意してください。