goo blog サービス終了のお知らせ 

マイコン工作実験日記

Microcontroller を用いての工作、実験記録

サポートするSCSIコマンド

2009-02-22 21:09:38 | USB
MSD(Mass Storage Device)の実装を開始したところ、Windows XPは最初に次の2つのSCSIコマンドを出してくることがわかりました。
Inquiry
  デバイスの種類や名称といった基本的な情報を返す
Read Format Capacities
  デバイスのサポートするブロック数を返す

ところが、ATMELが提供するサンプルのコードでは Read Format Capacitiesはサポートされていません。どうやら、Read Capacityというコマンドはサポートされており、それで用が足りるということのようです。少し気になったので、他のサンプルコードでの実装がどうなっているかを簡単に調べて比較してみることにしました。比較対象としたのは、秋月でも売っているAVRを使ったAT90USBKeyのコードとSTM32用のUSB Developer Kitです。

CommandAT91SAMUSBKeySTM32
Inquiry
Read Format Capacities××
Read Capacity(10)
Mode Sense(6)
Mode Sense(10)×
Read(10)
Write(10)
Request Sense
Test Unit Ready
Verify(10)
Prevent/Allow Medium Removal
Start/Stop Unit××
Format Unit××

どれだけ真面目に実装処理しているかまでは調べていません。単にコマンドをデコードする部分で比較しただけですが、STM32にはRead Format Capacitiesがあったので、同じように処理してやることにしました。やっていることは、確かにRead Capacityとほとんど同じで、ブロック数とブロック長さを返しているだけのようです。

Read Format Capacitiesでは、ホストであるWindows XP側は252バイトの応答を受けられるように待っていますが、実際に送信する応答データは12バイトしかありません。このように応答が短い場合にはendpoint haltの手順を使って応答データがそれで終わりであることを通知する必要があるということで、その処理を追加。続いて、WindowsはRead Capacityコマンドを送ってきています。Read Format Capacitiesとの使い分けの意味を理解するには、SCSIコマンドをまじめに勉強しないといけないのでしょうが、今回はパスして先に進むことにします。

原因はPCにあった

2009-02-18 23:54:32 | USB
わたしの使っているLet's NoteでUSB複合デバイスのインストールができなかった問題ですが、Tsuneoさんからのコメントを参考にsetupapi.logを調べたことろ、わたしのPC側の問題であることが判明しました。

わたしのPCでのログ内容は、次のようになっていました。
#-019 ハードウェア ID を検索しています: usb\vid_03eb&pid_6132&rev_0003,usb\vid_0
3eb&pid_6132
#-018 互換性のある ID を検索しています: usb\devclass_00&subclass_00&prot_00,usb\
devclass_00&subclass_00,usb\devclass_00,usb\composite
#-166 デバイス インストール関数: DIF_SELECTBESTCOMPATDRV。
#W059 最も互換性のあるドライバの選択に失敗しました。 エラー 0xe0000228: このデバ
イスと互換性のあるドライバがありません。
#W157 既定のインストーラは失敗しました。 エラー 0xe0000228: このデバイスと互換性
のあるドライバがありません。
#I060 選択したドライバの設定
#-166 デバイス インストール関数: DIF_INSTALLDEVICE。
#I125 USB\VID_03EB&PID_6132\001 の NULL ドライバをインストールしています。
#I121 USB\VID_03EB&PID_6132\001 のデバイス インストールは正しく終了しました。

これだけだと、「適切なドライバが無い」と言われているだけです。そこで、ちゃんとインストールできたカミさんのPCのログを調べてみると
#-018 互換性のある ID を検索しています: usb\devclass_00&subclass_00&prot_00,usb\
devclass_00&subclass_00,usb\devclass_00,usb\composite
#-198 コマンドラインは処理されました。: C:\WINDOWS\system32\services.exe
#I022 C:\WINDOWS\inf\usb.inf で "USB\COMPOSITE" が見つかりました; デバイス: "USB
 複合デバイス"; ドライバ: "USB 複合デバイス"; プロバイダ: "Microsoft"; Mfg: "(標
準 USB ホスト コントローラ)"; セクション名: "Composite.Dev"
#I023 実際のインストール セクション: [Composite.Dev.NT] ランク: 0x00002003. ドラ
イバ有効開始日: 07/01/2001.
#-166 デバイス インストール関数: DIF_SELECTBESTCOMPATDRV。
#I063 選択されたドライバは "c:\windows\inf\usb.inf" のセクション [Composite.Dev]
 からインストールされます。
となっており、何やらusb.infファイルを参照していることがわかりました。そこで、再度Let's Noteの方を確認してみると、なんとusb.infファイルが無いではありませんか。。

カミさんのマシンからusb.infをコピーしてくることで、問題を解決することができました。どうしてusb.infが無くなってしまったのかはわかりませんが、以前何度もblue screenを見た時に削除されているのかもしれません。

これで当初の計画どおりにCDC+MSDの複合デバイスのサポートに取り組めそうです。Tuneoさん、ありがとうございました。

原因はPCにあるのか?

2009-02-15 23:17:14 | USB
どうやらわたしは Windowsの迷宮に入りこんでしまっていたようです。

CDC+MSDのドライバがインストールできずに試行を繰り返していましたが、別のPCで試してみようと思いカミさんのノートPCにつなげてみたところ、アッサリとインストールできていまいました。MSDの処理はまだ動いていないので、デバイスマネージャの表示はこんな↓感じです。ちゃんと複合デバイスとして認識されています。



マイコン側でシリアルポートに出してみたUSBの動作ログは次のようになりました。16進数で表示されている部分は、MSDのOUT側エンドポイントに入ったリクエストをダンプしたものです。最初の4文字はUSBCになっており、SCSIコマンドを運ぶCBW(Command Block Wrapper)を受信できていることが確認できます。



マイコン側が原因ではないようなので喜んでもいいのかもしれませんが、自分が開発に使っているLet's Noteでインストールできないのはやはり不便です。いったい何が悪いのでしょうか? CDCだけならちゃんとINFファイルのインストールもできて動作するので、やはり複合デバイスの扱いに問題があるのでしょうか?あるいは、わたしのPCのレジストリが壊れてしまっていて、その結果おかしな動作になっているのでしょうか?

Windows XPについては もうお手上げなので、しばらくはMSDだけにして開発作業を進めていくことにしようかと思います。

複合デバイスのインストールができない

2009-02-14 22:04:26 | USB
CDC+MSDの複合デバイスの作業を開始しました... が、さっそくつまずいています。

まずは試しにDevice DescriptorとConfig Descriptorだけを変更してみました。実際はCDCの機能しかないのですが、とりあえずDevice/Config descriptorだけATMELのサンプルを元にしたものに入れ替えてみて、あたかも複合デバイスであるかのように見せかけることで、Windows側の動きを確認してみるのが目的です。

ビルドしてPCにUSBを挿しこんでみると、新しいデバイスとして認識され、ウィザードが起動されるところまでは順調に動きました。ところが、INFファイルを読み込ませても、次のように「インストールできません」エラーになってしまいます。



デバイスマネージャで確認してみると、エラーとなったデバイス名はSerial and SD cardと表示できています。この名前はUSBのProduct Descriptorとして与えた名前ですので、Device Descriptorの読み込みとString Descriptorの読み込みはちゃんとできていることはわかります。マイコン側のトレースから判断すると、Config Descriptorも送っているハズなのですが。。



プロパティにもIDは正しく入っているようです。



Windowsinfディレクトリを確認してみたところ、INFファイルはちゃんと読みこめているようです。そうすると、Windowsはいったい何が気に入らないのでしょうか??? USBのポートを替えてみたりとか、いろいろやってみたのですが症状は変わりません。うーん、困りました。

下調べ

2009-02-11 21:18:43 | USB
USBでCDC+MSDの複合デバイス機能を追加するにあたり、まずは情報収集です。

なにはともあれ、ATMELのAT91 Software Packageの内容を確認。前回、SDカードのコードをここから拝借した際にCDC+MSDのサンプルが存在することには気が付いていたので、こいつを参考にさせていただくことにします。なんと言っても、複合デバイスのConfiguration Descriptorと Windows用のINFファイルが用意されているのが助かります。複合デバイスのConfiguration Descriptorは、構造的にも複雑なものになっているようです。ほんとはUSBの理解を深める勉強材料のひとつなのでしょうが、自分でディスクリプタを用意する際にディスクリプタ長を間違えたりすると、Windowsにつなげた時にblue screenを見るハメになるのを経験的に知っているので、これはもうサンプルを使わせていただくことにします。Vendor ID, Product IDもそのまま使うことで、提供されているINFファイルを利用することもできますし。

ちょっと意外だったのはCDC+MSDの複合デバイスを使うには、Windows XP側ではSP3が必要だということ。SP2ではHot Fixが出ていたようです。Skype電話機のように HID+Audioの複合デバイスなら数多く使われているわけですが、CDC+MSDのような複合デバイスについては、それほどのニーズがないためにちゃんとサポートできていなかったということなのでしょうか?

MSDも今回初めて挑戦する項目ですので、USB.ORGからMass Storage Classの仕様書を入手。概要だけならATMELのAPノートの方が要点が整理されてあり、わかりやすい感じです。ざっと読んでみて次のようなことを学習しました。
  1. SDやフラッシュのようなデバイスをサポートするには、Bulk-Only Transport(BOT)というトランスポート層プロトコルを使う。その名前の示すとおり、BULKのパイプしか使わない。
  2. デバイスの制御にはSCSIコマンドを使うが、SCSIコマンド/レスポンスとR/Wのデータの両方を上述のようにBULKパイプを使って流す。
  3. BULK転送は最大64バイト。1ブロック(512バイト)を送受するには8回の転送が必要となる。
やりとりにSCSIコマンドを使うということは、以前なにかの記事で読んで知っていたのですが、データとコマンドは別のパイプを使うものと思い込んでいました。BULKの転送量についても改めて認識。AT91SAM7Sではもともと、エンドポイントのバッファ長は最大64バイトしかサポートしていないのですが、AT91SAM7A3のEP4とEP5では512バイトサポートできます。1度で1ブロック運べるかと思っていましたが、そうではないのですね。

なんとなくMSDの概要は理解できましたが、SCSIコマンドの詳細までは追いかけていません。サンプルを参考にしながら、実際にWindowsとつなげてみて必要なものだけ実装していくつもりでいます。

複合デバイスのサポートに向けて

2009-02-09 00:42:08 | USB
通話音声をSDカードに録音できるようになりましたが、それを再生する手段がまだ単独では用意できていません。いまのところSDをPCに挿し直して、PCで再生しているのですが、チョット面倒です。再生するための特別な番号をダイアルすることにしてもいいのですが、USBでPCにつなぐと外部ディスクに見えるようにしてやり、PCで再生する方法もあります。

つまりは、MSD (Mass Strage Device)クラスを実装してやればいいわけです。今まで使っているCDCと両方をサポートできる複合デバイスをサポートすることに挑戦しようかと考えています。



これまではUSB CDCでつないだPCにデバックメッセージを表示させていましたが、こんどはUSB部分をいじることになるので、デバックシリアルを使うことになります。そういうわけで、3ピンのコネクタを立てて、シリアルポートの準備完了です。複合デバイスはおろか、MSDも実装したことないので、しばらくはUSBの勉強をすることになりそうです。