.NET CF アプリケーションとカーネルランドを一緒にデバッグ(1/2)Windows Developer Days (2012/04/24-25)

.NET CF アプリケーションとカーネルランドを一緒にデバッグ(2/2)

2012/04/13 koga

前回の続きです。アプリケーションとカーネルランドを一緒にデバッグするやり方に関連して、いくつか補足します。

■カーネルデバッガと一緒に動かす場合の設定(※ネットワークインタフェースが一つだけの場合)
さて、カーネルデバッガとアプリケーションデバッガを一緒に動かす場合、一つ注意しなければいけません。それは、WinCE/WEC に固定 IP アドレスを設定する場合のレジストリキーです。前回の「ターゲットボードとホスト PC を直結する場合」の説明で、IP アドレスを設定する場合のレジストリキーが
 [HKEY_LOCAL_MACHINE\Comm\<アダプタ名>\Parms\Tcpip]
だと書きました。カーネルデバッガを動かす場合、この「アダプタ名」が、動かさない時と違う場合があるのです。それは、ターゲットボードにネットワークインタフェースが一つしかなく、アプリケーションデバッガの Ethernet 接続と、カーネルデバッガの Ethernet 接続が、一つのネットワークインタフェースを共有する(つまり、Ethernet ケーブルを一本しか使わない)場合です。

その場合、カーネルデバッガを動かす時は、アダプタ名として “VMINI1″ を指定しなければいけません。VMINI1 というのは、前回の例で示した “FEC1″ のような、Ethernet コントローラを直接制御するデバイスドライバではなく、仮想のネットワークデバイス(論理デバイス)のアダプタ名です。この仮想ネットワークデバイス(VMini)は、リファレンスの次のページで説明されています:

 Ethernet Debugging Services (Windows Embedded CE 6.0)
 http://msdn.microsoft.com/en-us/library/ee478406(v=winembedded.60).aspx

WEC 7 のリファレンスには、VMini について説明した個所が見当たりません。もしかすると、WEC 7 からは、VMini の使用を推奨しておらず、そのため、説明を省略しているのかも知れません。なお、KITL についてご存じの方は、ここと、次の説明(「KITL について、もう少しだけ」)は飛ばして下さい。

以下は、KITL について詳しくない方のための説明です。

上のページの図を見ると、”VBridge” というモジュールが、”Vmini.dll” と “EDBG” の二つのモジュールに繋がっており、”Vmini.dll” は、NDIS インタフェースを介して TCP/IP スタックと繋がっています。この “VBridge” が、カーネルデバッガとアプリケーションデバッガが一つのネットワークインタフェースを共有するためのモジュールで、”Vmini.dll” が VMini のことです。VMini は、ネットワークインタフェース、つまり Ethernet コントローラを直接制御せず、VBridge に委譲して間接的に制御します。VBridge は、VMini に加えて、”EDBG”、つまり、カーネルデバッガが使用する Ethrnet 通信機能のモジュールに対してもネットワークインタフェース機能を提供します。

この VBridge の仕組みから分かるように、カーネルデバッガは、Ethernet 経由でホスト PC と通信しますが、TCP/IP スタックは使用せず、独自のプロトコルで通信します。TCP/IP スタックは、カーネルの上位にありますから、カーネルデバッガが TCP/IP スタックを利用することは、できないのです。カーネルデバッガがホスト PC と通信するプロトコルは、KITL (Kernel Independent Transport Layer) と名付けられており、上のページの一つ上のドキュメント階層で説明されています。

 Kernel Independent Transport Layer (Windows Embedded CE 6.0)
 http://msdn.microsoft.com/en-us/library/ee479323(v=winembedded.60).aspx

 Kernel Independent Transport Layer (Windows Embedded Compact 7)
 http://msdn.microsoft.com/en-us/library/ee479323.aspx

KITL の説明は、WEC 7 のリファレンスにもあり、どちらも同じ図が載っています。この図の “KITL” の、”Device hardware” に近い側の部分(下側の部分)に先ほどの図の “VBridge” があり、そして、”Kernel debugger” に近い側の部分(上側の部分)に “EDBG” があると考えて下さい。

本題に戻ります。ネットワークインタフェースが一つしかなく、それを KITL と TCP/IP スタックで共有する場合、通常の Ethernet コントローラのドライバでは対応できません。そのため、通常の Ethernet コントローラのドライバ(先の例の “FEC1″)は使われず、VMini が代わりに OS イメージに組み込まれ、VBridge の働きにより、TCP/IP スタックと KITL がネットワークインタフェースを共有する、というわけです。そのため、固定 IP アドレスを設定する場合、レジストリキーで指定する TCP/IP スタックのアダプタ名を、VMini のアダプタ名である “VMINI1″ にしなければいけないのです。

■KITL について、もう少しだけ
ところで、KITL は Ethernet 接続でしか使えないかといえば、そうではありません。Kernel *Independent* Transport Layer という名前の通り、Ethernet 以外の様々な伝送路に対応できます。そして、Ethernet の KITL を使用して、TCP/IP スタックと Ethernet コントローラを共有する場合は、TCP/IP スタックが Ethernet コントローラを占有する場合に比べて、Ethernet による通信のパフォーマンスが低下します。これは、同時に二種類の通信が同じ伝送路を使うせいでもでありますし、また、VMini と VBrige、および、VBridge が呼び出す Ethernet コントローラの制御ルーチン(※この制御ルーチンは、OAL の一部として実装されます)の組み合わせによる動作は、通常の Ethernet コントローラのドライバの単体動作に比べてオーバーヘッドが大きいため、パフォーマンスを出しづらい、という事情もあると思われます。

そのため、WinCE/WEC のネットワークのパフォーマンス評価を行う場合は、VMini を無効にした状態で行うようにという注意書きがリファレンスに書かれています。上の KITL の説明ページにも、KITL と OS(TCP/IP スタック)がハードウェアを共有するとパフォーマンスに悪影響がある、という但し書きがあります。

年々、組み込み機器用のプロセッサは高機能化が進み、多くの周辺機器のコントローラを内蔵するようになってきています。そのため、カーネルデバッガ/KITL と TCP/IP スタックが一つのネットワークインタフェースを共有しなくても、たとえば KITL にはシリアルや USB での接続を割り当て、Ethernet コントローラは TCP/IP スタックに占有させる、といった構成は可能です。逆に、プロセッサに内蔵された Ethernet コントローラはデバッグ専用にして KITL に割り当て、TCP/IP スタック用には、USB や SD の WiFi モジュールを使う、というような構成や、あるいは、安価な Ethernet コントローラを外付けして、そちらをデバッグ専用に使う、という方策も考えられます。

いずれにせよ、VMini による、TCP/IP スタックと KITL の共存は、デバッグ専用のものであり、通常構成で使うものではありません。もちろん、Ethernet コントローラのドライバをデバッグする場合には、VMini は利用できません(※Ethernet コントローラのドライバをデバッグしようとすると、同じコントローラを使う KITL の動作に影響を与えるから・・・ではなく、そもそも、デバッグしたいドライバの代わりに VMini が動作するので、デバッグする方法がありません)。

■ソースコードも、見てみましょう
上で述べた VBridge は、KITL (kitl.dll) に組み込まれるモジュールとなっており、そのソースコードは、WEC 7 と WinCE 6.0 のソースツリーの、それぞれ次の場所にあります:

 ・WEC 7
  %_WINCEROOT%/platform/common/src/common/kitl/

 ・WinCE 6.0
  %_WINCEROOT%/PUBLIC/COMMON/OAK/DRIVERS/ETHDBG/VBRIDGE/

WinCE 6.0 では、VBridge は vbridge.lib という static library でしたが(※ソースファイルが vbridge.c 一つだけのライブラリ)、WEC 7 では、oal_kitl.lib という static library にまとめられています。oal_kitl.lib は、WinCE 6.0 にもありますが、VBridge は別のライブラリになっていました。WEC 7 になって、VBridge(vbridge.c) が oal_kitl.lib にまとめられた、というわけです。

ちなみに、カーネルデバッガの OS 側モジュール(kd.dll)のソースコードは、WEC 7 も WinCE 6.0 も、次の場所にあります:

 %_WINCEROOT%/private/winceos/COREOS/nk/kdstub/

興味のある方は、どのような実装になっているのか、ソースコードをご覧になってみると面白いんじゃないかと思います。

■おまけ:ネイティブコードのアプリケーションの場合
さて、.NET CF アプリケーションではなく、ネイティブコード(アンマネージドコード)のアプリケーションをデバッグする場合は、どうなのでしょうか?

Visual Studio の「スマートデバイス」プロジェクトで作成したネイティブコードのアプリケーションをデバッグする手順は、.NET CF アプリケーションの場合と同様です。前回と今回で説明した手順を使えば、ネイティブコードのアプリケーションも、カーネルランドと一緒にデバッグできます。試してみて下さい。

ここで、注意深い方であれば、「あれ?」と思われたかも知れませんね。前回の説明では、冒頭で次のように書いたからです:

 皆さんご存じの通り、ネイティブコードのアプリケーションの場合には、アプリケーションもカーネルランドも、どちらもカーネルデバッガでデバッグできます。

これは、何だったのでしょうか?前回の冒頭で書いたのは、OS Design のサブプロジェクトとしてアプリケーションを作成した場合のことを念頭に置いていました。つまり、OS イメージをビルドする際に、OS と一緒にビルドして、デフォルト設定では OS イメージに組み込まれるようにした場合のことを指していたのです。その場合は、カーネルデバッガを使って、カーネルランドと同時にアプリケーションをデバッグできます。

では、OS Design のサブプロジェクトで作成したアプリケーションではなく、Visual Studio の「スマートデバイス」プロジェクトで作成したネイティブコードのアプリケーションは、カーネルデバッガを使ってデバッグできないのでしょうか?実は、できます。

Visual Studio の「スマートデバイス」プロジェクトで作成したネイティブコードのアプリケーションを、カーネルデバッガでデバッグするには、アプリケーションの実行ファイル(.exe)とプログラムデータベースファイル(.pdb)を、カーネルデバッガが認識できる場所に置けばよいのです。OS Design のカタログ項目で、”Target Control Support(Shell.exe)” か “Release Directory File System” を選択して OS イメージをビルドしておき、Flat Release Directory に、デバッグしたいアプリケーションの .exe と .pdb をコピーする、というのが一番お手軽だと思います。こうしておけば、わざわざアプリケーションデバッガを別に動かさなくとも、カーネルデバッガだけで、アプリケーションとカーネルランドを一緒にデバッグできます。

たとえば、OS を開発するチームとアプリケーションを開発するチームが分かれていて、アプリケーションで不具合が起きた場合に、不具合の要因がアプリケーション側にあるのか OS 側にあるのか切り分け調査を行うなどの場合、この方法は便利かも知れません。アプリケーション開発チームは、OS Design のサブプロジェクトではなく、Visual Studio の「スマートデバイス」プロジェクトでアプリケーションを作成するのが一般的だと思います。そのような場合に、カーネルランドとアプリケーションを同時または一緒にデバッグする方策は、次のものが考えられます:

  1. カーネルデバッガとアプリケーションデバッガを各々動かして、カーネルランドとアプリケーションを一緒にデバッグする。
  2. 「スマートデバイス」プロジェクトを OS Design のサブプロジェクトに作り直し、アプリケーションを OS Design に組み込んだうえで、カーネルデバッガを使ってカーネルランドとアプリケーションを一緒にデバッグする。
  3. 「スマートデバイス」プロジェクトは、そのままにして、アプリケーションの .exe と .pdb を Flat Release Directory にコピーしてからカーネルデバッガを動かす(上述した方法)。

上の1は、前回と今回の主題である、.NET CF アプリケーションをカーネルランドと一緒にデバッグするのと同じ方策です。2と比べると、3の方が手間が少ないのは明らかです。1と3を比べても、カーネルデバッガだけで作業できるという点で、3の方が、より手間が少ない方法です。

■おまけ2:その他の参考資料
前回と今回では、カーネルランドと一緒(または同時に)アプリケーションをデバッグするにはどうすればよいか、ということを説明しました。「スマートデバイス」プロジェクトで作ったアプリケーションだけをデバッグする場合については、Visual Studio のリファレンスに説明があります。いくつかのトピックが取り上げられていますので、ご覧になってみて下さい:

 Debugging Device Projects
 http://msdn.microsoft.com/en-us/library/ms180772(v=vs.90).aspx

ネイティブコードのアプリケーションに関しては、MFC や ATL を使ったアプリケーションをビルド・デバッグする場合の注意点や手順についても、解説されています。

 Building and Debugging Visual C++ Device Projects
 http://msdn.microsoft.com/en-us/library/c5fc53wa(v=vs.90).aspx

Entry Filed under: .NET Compact Framework, OS の内部動作, アプリケーション開発, 開発環境

1 Comment Add your own

  • 1. Srinivasan  |  5月 4th, 2012 at 19:23

    Way to use the intrneet to help people solve problems!

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Categories

Links

Posts by Authors

Recent Posts

Calendar

2012年4月
« 3月   5月 »
1234567
891011121314
15161718192021
22232425262728
2930  

Posts by Month

Posts by Category

Meta