バックナンバーはこちら

today&tomorrow

Technology Update

2018 vol.110

バーチャル・プロトタイプを使用した組込みソフトウェアのデバッグ

著者:Achim Nohl(シノプシス、ソリューション・アーキテクト)

組込みソフトウェアのデバッグ

デバッグとは、ソフトウェアから不具合を取り除くプロセスをいいます。このプロセスは、大きく次のフェーズで構成されます。

  • 不具合をトリガーする
  • 不具合の症状を検出する
  • 根本原因を解析する
  • 同じシナリオを再現する

再現性と予測性の高い、解析に役立つデバッグ・プロセスを構築するには、ターゲット・ハードウェアおよびデバッグ・ツールに以下の3つの基本的性質が求められます。

  • 確定性
  • 可制御性
  • 可視性

確定性は、シナリオを確実にトリガーおよび再現する上で必要な要素です。多くの場合、不具合は散発的またはランダムに発生するように見えるため、プロジェクト管理の点から見るとデバッグは予測不可能でリスクの大きい作業となっています。しかし確定性がないように見えても、ターゲット・ハードウェアの可制御性が十分でないためにそう見えているだけのことがよくあります。たとえばタッチスクリーン/キーボード・イベント、Ethernetパケット、センサー・データなどのシナリオにおけるイベントのシーケンスと到着時間は予測可能なフローでは制御できず、組込みソフトウェアで不具合が発生することもあれば隠れてしまうこともあります。このようにシナリオを確定的に再現するためには可制御性が重要な役割を果たします。

確定性は不具合の解析においても重要な要素となります。ハードウェアおよびソフトウェア・ステートへの可視性に加え、ターゲット・ハードウェアと同期してソフトウェアを命令単位で実行できる必要があります。命令はプログラムの文を構成する最小単位で、レジスタやメモリーに書き込んだり、他のシステム・ブロックに対する信号をトリガーしたりして下層のハードウェアを読み出し/変更します。したがって命令文の影響を観察および解析するには、システムと同期して命令を実行できる必要があります。また、その他すべてのCPUやハードウェア・ペリフェラルが実行を中断することも必要です。デバッグのためにシステムの実行を中断している間は、既に開始したウォッチドッグがタイムアウトをトリガーすることはありません。ソフトウェアのステップ実行の次に重要なのが、デバッグ・ターゲットがフリーラン・モードのときにシステムの実行を中断するトリガーを定義する機能です。最も単純な例として、特定の位置でプログラム実行を中断するブレークポイントがあります。ブレークポイントの設定は、ハードウェア機能によって制限されることがあります。一般に、ROMコードにはごくわずかなブレークポイントしか設定できないため、ソフトウェア・ブレークポイントを使用する必要があります。この場合、デバッガはRAM内の特定の位置に特別なソフトウェア割り込み/トラップ命令を挿入し、これをデバッガで処理します。たとえばソフトウェアを開発する際、新しいセンサー・データがセンサーUARTに到着した時点でただちに実行を中断し、ペリフェラルから割り込みサービス・ルーチン、UARTドライバ、センサー・ドライバを経由してセンサー・ミドルウェア/アプリケーションに到達するまでのフローをデバッグしたいことがあります。

問題の症状をデバッグする際には、ハードウェアおよびソフトウェア・ステートに関してシステム全体の可視性が必要です。ハードウェアに対する可視性を得るには、JTAGやエンベデッド・トレース・モジュールなど専用のデバッグ・ロジックが必要です。不具合が発生したときの症状とその原因を理解および認識するのにかかる時間は、提供される可視性のレベルに大きく左右されます。デバッグでは不具合をいかに効率よく解析、理解できるかが生産性の鍵を握りますが、それにはコストがかかる上、事前に選択されたごく一部のレジスタやメモリーしか可視化できないこともしばしばです。このように可視性が制限されると開発者は問題を完全には評価できず、解釈の余地が残ってしまいます。場合によってはペリフェラルの内部ステート、あるいはペリフェラル間の信号についての可視性も必要になることがあります。実際には、あるブロックから割り込みが発生していないことが分かれば、何がその妨げになっているのかを知るヒントが得られます。また、パワーアップやパワーダウンなど電源ステートの遷移中に可視性を確保するのは困難なことがよくあります。多くの場合、JTAG TAPロジックは電源ドメインに属しており、パワーダウンしている間はデバッグが行えません。こうしたデバッグの制約に加え、パワー・マネジメントは複雑さを増しており、ソフトウェア・ドメインと複雑に絡み合ったパワー・マネジメントに関するデバッグの負担も増大しています。

要するに、現在のデバッグ・ソリューションは下層のハードウェアおよびソフトウェア・スタックの複雑化に対応しきれておらず、問題を適切に解析/理解できないために推測と試行錯誤での問題解決を余儀なくされています。このような試行錯誤は対症療法に終わることが多く、このような方法でバグを抑制してもデバイスの量産開始後に同じバグが再び現れることがあります。したがって、可制御性、可視性、確定性が相互排他の関係になることもしばしばです。一般に、これよりも高度なデバッグ機能を提供できるのはエミュレータしかありません。ここからは、バーチャル・プロトタイプを使用してデバッグの大きな課題を解決し、実機完成のはるか前からソフトウェア開発を開始できるようにする方法についてご説明します。

バーチャル・プロトタイプの紹介

バーチャル・プロトタイプ(VP)は、システムの機能動作をソフトウェア開発者のホスト・マシン上でシミュレーションします。バーチャル・プロトタイプは、ソフトウェア開発者にとって関係のあるシステム・コンポーネントの機能モデルを組み合わせて構築します。バーチャル・プロトタイプでは、実機上で動作するのとまったく同じバイナリ・ソフトウェア・イメージを実行できます。しかも、バーチャル・プロトタイプは物理的なハードウェアの完成時期よりもはるかに早い段階で利用できます。SystemC TLM-2.0で標準化されたモデル・インターフェイスと市販のモデル・ライブラリ、そしてシノプシスVirtualizer™のようなバーチャル・プロトタイプ・オーサリング・ツールを使用すると、通常は12か月ほどスケジュールを前倒しして開発を開始できます。

組込みソフトウェアの特徴

図1に示すように、最近の携帯電話向けICは多くのサブシステムで構成されており、それぞれがソフトウェアを必要とします。この結果、ブート・モニタ、オペレーティング・システム、ユーザー空間ソフトウェア、およびさまざまなサブシステム上で動作するソフトウェア・スタックを含め、デバイスのブートアップ全体のシミュレーションが可能です。このコンテキストでは、組込みソフトウェアはI/Oペリフェラルを使用して「実世界」と接続します。たとえばブート・コードはUSBホスト・コントローラ・ペリフェラルを使用して最新のOSイメージをDRAMにダウンロードします。この場合、USBホスト・コントローラ・モデルはバーチャル・プロトタイプのいわゆるバーチャルI/O機能を利用してホスト上のUSBデバイスに接続します。UART、Ethernet、SATA、MIPIなどのバーチャルI/Oをサポートしたその他の通信I/Oペリフェラル・モデルについても同様です。

バーチャル・プロトタイプによっては、ソフトウェア開発に関係のないペリフェラル機能を抽象化することもあります。このように任意の機能を抽象化できるのはバーチャル・プロトタイプの利点の1つです。これによりソフトウェア開発の複雑さを抑え、最適なソフトウェア開発計画を立てることができます。物理ハードウェアを使用した場合はこれとは対照的に、オペレーティング・システム(OS)でDRAMを使用するにはブート・コードでダイナミック・メモリー・コントローラをセットアップする必要があります。ブート・コードを有効にしないとOSのブリングアップを開始できません。バーチャル・プロトタイプの場合、ソフトウェア開発者の判断によって最初はメモリー・コントローラをモデル化せず、コンフィギュレーションなしで使用できる純粋なストレージとしてDRAMを表現するといった柔軟な利用が可能です。こうするとブート・コード開発とOSブリングアップを互いに独立して実行でき、ソフトウェア開発の観点からはOSの前にブート・コードを有効にしておくという依存性をなくすことができます。

画像

図1:バーチャル・プロトタイプを使用したソフトウェア開発環境

カテゴリートップ