web-dev-qa-db-ja.com

組み込みソフトウェアの単体テスト

組み込みシステムに固有の組み込みソフトウェアの単体テストで使用したベストプラクティスは何ですか?

61

組み込みソフトウェアは過去10年間で大きな進歩を遂げたかもしれませんが、一般的には次のことを行いました。

  • ターゲットハードウェアに依存しないアルゴリズムの場合、組み込みでないプラットフォームでビルドおよびテストされた単体テストがありました。
  • ハードウェアを必要とするものについては、ユニットテストが条件付きでコードにコンパイルされて、利用可能なハードウェアを使用しました。私たちの場合、それはターゲットのシリアルポートであり、結果が別のより機能の高いマシンにプッシュされ、そこでテストの正確さがチェックされました。
  • ハードウェアによっては、埋め込まれていないプラットフォームで「仮想」デバイスをダミーにする場合があります。これは通常、プログラムが使用するメモリを変更する別の実行スレッド(またはシグナル関数)で構成されていました。メモリマップI/Oには役立ちますが、IRQなどには役立ちません。
  • 通常、一度に単体テストできるのは、完全なコードの小さなサブセットのみです(メモリの制約のため)。
  • 時間に敏感なもののテストのために、私たちはしませんでした。簡潔でシンプル。使用したハードウェア(8051および68302)は、実行速度が遅すぎると機能しない場合がありました。この種のデバッグは、最初はCRO(オシロスコープ)で、そして(少しお金があったら)ICE(インサーキットエミュレーター)で行う必要がありました。

うまくいけば、私が最後に行ってから状況が改善されたと思います。私の最悪の敵にそのような痛みを感じたくありません。

51
paxdiablo

PC環境での単体テスト(PC Cコンパイラを使用してコードをコンパイルし、PC単体テストフレームワークでコードを実行する)によって、いくつかの条件が付くことが多く得られます。

  1. これは、スタートアップコード、RAMテスト、ハードウェアドライバーなど)を含む低レベルコードのテストには適用されません。これらのより直接的なユニットテストを使用する必要があります。
  2. 組み込みシステムのコンパイラは信頼できるものでなければならないので、コンパイラによって作成されたバグを探す必要はありません。
  3. コードは、ハードウェアを抽象化したレイヤードアーキテクチャでなければなりません。 PCユニットテストフレームワーク用のハードウェアドライバーシミュレーターを作成する必要がある場合があります。
  4. プレーンなstdint.hなどではなく、常にuint16_tなどのunsigned intタイプを使用する必要があります。

これらのルールに従い、PCの単体テストフレームワークでアプリケーション層のコードを単体テストした後、それが適切に機能することを確信できることがわかりました。

PCプラットフォームでの単体テストの利点:

  1. ユニットテストフレームワークを追加することにより、組み込みプラットフォームのROMスペースが不足するという問題に直面することはありません。
  2. コンパイル-リンクの実行サイクルは、通常、PCプラットフォームでより速くて簡単です(数分かかる可能性のある「書き込み/ダウンロード」ステップを回避します)。
  3. 進行状況の視覚化(一部の組み込みアプリケーションのI/Oペリフェラルが制限されている)、分析用の入出力データの保存、より時間のかかるテストの実行には、より多くのオプションがあります。
  4. 組み込みプラットフォームでは利用できない/適切でない、すぐに利用できるPCベースの単体テストフレームワークを使用できます。
20
Craig McQueen

組み込みシステムは幅広いトピックですが、一般的には、ハードウェアとソフトウェアの両方を組み合わせた特定目的の製品と考えてみましょう。私の組み込みの背景は、すべての組み込みシステムのほんの一部である携帯電話からのものです。以下の点を抽象化するために少し注意を払います。

  • 可能な限りハードウェアの依存関係を抽象化します。このようにして、モックされた「ハードウェア」でユニットテストを実行し、ターゲットでのテストが困難なまれな例外的なケースをテストすることもできます。抽象化コストを防ぐには、たとえば条件付きコンパイル。

  • ハードウェアへの依存をできるだけ少なくします。

  • エミュレーターまたはクロスコンパイラー環境でユニットテストを実行しても、コードがターゲットハードウェアで動作することは保証されません。ターゲットでもテストする必要があります。できるだけ早くターゲット上でテストします。

13
laalto

James W. Grenningによる Test Driven Development for Embedded C を確認してください。この本は2010年8月に発行される予定ですが、ベータ版の本は現在 The Pragmatic Bookshelf で入手できます。

13
Matthew Rankin

かなりのハードウェア依存コードをシミュレーターを使用してテストし、Keilのシミュレーターを使用して、IDE(関連ツールではなく、ツールを使用する)を使用しています。 'それが反応することを期待する方法で、作業コードをかなり確実にテストすることができます。一部のテストではハードウェアをモデル化するのに多少の労力が必要ですが、ほとんどの場合、これは非常にうまく機能し、多くを得ることができますハードウェアを使用せずに完了しました。ハードウェアにアクセスする前に、シミュレータでほぼ完全なシステムを動作させることができ、コードを実際のものに配置すると、対処する問題がほとんどありませんでした。これにより、製造の速度も大幅に向上します。 PCですべてを実行できるため、チップをシミュレートしながらハードウェアですべてを実行するよりも詳細なデバッガーを使用してすべてを実行できます。

これは、複雑な制御システム、メモリインターフェイス、カスタムSPI駆動のIC、さらにはモノディスプレイでさえも、確実に機能するようになりました。

6
radix07

ここでは未経験の声ですが、これも最近考えていることです。最良のアプローチはどちらかだろうと私には思われる

A)ターゲットに書き込む前に、PC環境で可能な限りハードウェアに依存しないアプリケーションコードを記述し、同時にユニットテストを記述します(最初にPCでこれを行うと、強制的にハードウェアに依存しないものを分離します)。この方法では、選択したユニットテスターを使用して、ハードウェアに依存するものを昔ながらの方法でテストできます。RS-232やオシロスコープ、およびI/Oピンは、実行に必要な速度に応じて、時間依存のデータを送信します。 。

B)すべてをターゲットハードウェアに書き込みますが、ユニットテストを実行し、RS-232またはその他の方法で結果(または結果を分析できるデータ)を出力するユニットテストビルドを条件付きでコンパイルするmakeターゲットがあります。メモリが不足している場合は、注意が必要です。

編集2009年7月3日編集ハードウェアに依存するものを単体テストする方法について、もう1つ考えました。ハードウェアイベントが速すぎてRS-232で記録できないが、大量のオシロスコープデータチェックを手動で切り替えて、I/Oピンフラグが期待どおりに上昇または下降するかどうかを確認したくない場合は、PCを使用できます。これらの信号のタイミングを自動的に評価する統合DIO(National Instrumentsのデータ集録カードラインなど)を備えたカード。次に、PCにソフトウェアを作成して、データ収集カードを制御し、現在実行中の単体テストと同期するだけです。

6
Sam Skuce

ここには良い答えがたくさんありますが、言及されていないいくつかのことは、次の目的で診断コードを実行することです:

    ログHALイベント(割り込み、バスメッセージなど)
    リソース(すべてのアクティブなセマフォ、スレッドアクティビティ)を追跡するコードを用意する
    ヒープとメモリのコンテンツを永続ストレージ(ハードディスクまたは同等のもの)にコピーして、デッドロック、ライブロック、メモリリーク、バッファオーバーフローなどを検出およびデバッグするためのキャプチャRAMメカニズムを備えています。
3
embdeddCoder

昨年これに直面したとき、組み込みプラットフォーム自体でテストしたかったのです。私はライブラリを開発していて、RTOS呼び出しと組み込みプラットフォームの他の機能を使用していました。利用できる具体的なものがなかったので、UnitTest ++コードを目的に合わせて調整しました。 NetBurner ファミリーであり、Webサーバーが組み込まれているため、従来のRED/GREENフィードバックを提供するWebベースのGUIテストランナーを作成するのは非常に簡単でした。 かなりうまくいった これで、単体テストがはるかに簡単になり、コードが実際のハードウェアで機能することを確信できるようになりました。統合テストを実行するために単体テストフレームワークを使用することさえあります。最初にハードウェアをモック/スタブし、そのインターフェースをテストですが、最終的には、実際のハードウェアを実行するman-in-the-loopテストをいくつか作成します。これは、ハードウェアについて学習するためのはるかに簡単な方法であり、埋め込まれたトラップから簡単に回復できる方法です。実行AJAX Webサーバーへのコールバックトラップは手動で呼び出した結果としてのみ発生しますテストの王様であり、システムは常にトラップの数秒後にきれいに再起動します。

NetBurnerは、書き込み/コンパイル/ダウンロード/実行のテストサイクルが約30秒になるほど高速です。

2
Tod

評価ボードでは多くの組み込みプロセッサが利用できるため、実際のI/Oデバイスがない場合でも、多くの場合、これらの種類のいずれかで大量のアルゴリズムとロジックを実行できます。 jtag。そして「ユニット」テストは通常​​、とにかくあなたのI/Oよりもあなたのロジックについてです。問題は通常、テスト成果物を戻すことですoutこれらの環境の1つ。

0
JustJeff

デバイス依存とデバイス非依存の間でコードを分割します。独立したコードは、それほど苦労せずに単体テストできます。スムーズな通信インターフェイスができるまで、依存するコードを手動でテストする必要があります。

書き込み通信インターフェースの場合は、ごめんなさい。

0
Paul Nathan