USBデバイスに生データを書き込む方法

USBデバイスに生データを書き込む方法

マイコンピュータに接続されているUSBデバイスに生データを書き込もうとしています。私はKali Linuxを使用しており、正しいファイルパスを見つけました: "/dev/usb/003/013" 。しかし、データを書き込もうとするとエラーが発生します。

root@kali:~/usb# printf "test" > /dev/bus/usb/003/013
bash: printf: write error: Invalid argument

私もキャットを使ってみました。

root@kali:~/usb# cat test > /dev/bus/usb/003/013 
cat: write error: Invalid argument

前者の場合、「test」ファイルが存在し、データが含まれています。ファイル記述子がありますが、システムはファイル記述子に書き込めないようです。

研究の最後に、私は次の結論に達しました。

A. デバイスに接続するにはUSBドライバが必要です。

B. SCSIパススルーを使用して、デバイスのエンドポイントに直接データを書き込みます。

私はUSBプログラミングが初めてで試してみたいのですが、以前にドライバを書いたことはありません。どんなアドバイスや助けにも感謝します。

もともと試したように生データをデバイスに書き込むことは可能ですか?そうでなければ、私が利用できるいくつかのオプションを説明できますか?

ベストアンサー1

USBデバイスは、単純な読み書きパイプよりもはるかに複雑です。これを機能させるにはコードを書く必要があります。 (おそらく)カーネルドライバを書く必要はありません。バラよりhttp://libusb.info(旧libusb.org)とhttp://libusb.sourceforge.net/api-1.0。 Linux、OSX、Windows、Android、OpenBSDなどで動作すると主張します。 Mac OS Xにはユーザーレベルの機能があります。入力/出力キットこれによりUSBにアクセスできます。 WindowsではWinUSBを使用できますが、複雑です。

これは、USBアーキテクチャを理解するのを助けるために私が描いた小さな図です。

                 ╭────────────────────────────────────╮
    ┌──────┐     │   device     ┌─────┐  ┌─────────┐  │
    │ Port ├──┐  │            ┌─┤ EP0 ├──┤ control │  │
    └──────┘  │  │ ┌────────┐ │ └─────┘  ├─────────┤  │
              ├────┤addr = 2├─┤ ┌─────┐  │         │  │
              │  │ └────────┘ ├─┤ EP1 ├──┤interface│  │
              │  │            │ └─────┘  │   #0    │  │
              │  │            │ ┌─────┐  ├─────────┤  │
              │  │            ├─┤ EP2 ├──┤         │  │
              │  │            │ └─────┘  │interface│  │
              │  │            │ ┌─────┐  │   #1    │  │
              │  │            └─┤ EP3 ├──┤         │  │
              │  │              └─────┘  └─────────┘  │
              │  ╰────────────────────────────────────╯
              :

要約:各デバイスには、アドレス(オペレーティングシステムによって割り当てられ変更される可能性があります)と最大32のエンドポイントがあります。

デバイスには1つ以上の「インターフェース」があります。たとえば、ウェブカメラは「カメラ」ポートと「マイク」ポートを提供できます。多機能プリンタは複数のインタフェースを提供します。

エンドポイント0はデバイスの制御と設定に使用され、他のエンドポイントはさまざまなインターフェイスにアクセスするために使用されます。各インターフェイスには、ゼロ以上(通常より多くの)エンドポイントがあります。

エンドポイントは、いくつかのトランスポートタイプのいずれかです。

  • 制御転送は、デバイスを照会および構成するために使用されます。各デバイスは最小限の制御ステートメントをサポートする必要があります。私は制御転送がエンドポイント0にのみ当てはまると思います。
  • 一括送信は、帯域幅全体でデータを送受信します。
  • 割り込み転送(一括転送とどう違うかわかりません。USBは割り込みを行いません)。例としてはキーボードとマウスがあります。
  • アイソクロナス伝送は、全帯域幅でデータを送受信するため、リアルタイムの要件がありますが、信頼性が欠けます。オーディオ/ビデオアプリケーション用。

また、注目すべき点は、USBデバイスには、使用可能なインターフェースなどを制御するためのいくつかの構成がある可能性があることです。デバイス構成の変更は、デバイスのプラグを抜き、その場で他のデバイスを接続するのとほぼ同じです。

これらの情報はすべて、デバイス記述子、構成記述子、インターフェース記述子、エンドポイント記述子などに配置され、エンドポイント0を介して照会できます。

(内部的にはデータはバイトストリームではなくパケットとしてパッケージ化されており、正確なフォーマットはUSB仕様の一部です。ほとんどの場合、コントローラとドライバがそれについて心配する必要はありません。この部分を管理してください。)

実際には、APIライブラリとOSに基づいてデバイスを検出し、さまざまな記述子を読んで現在扱っている内容を特定し、オプションで設定を設定し(OSで許可されている場合)、インターフェイスを開く必要があります。エンドポイントを開きます。

バッチエンドポイントの場合、生データを読み書きできます。制御転送のために、APIライブラリは関数呼び出しを提供します。私は割り込みや同期転送を使用したことがありません。 APIライブラリにこれに関するドキュメントがあると確信しています。


追加情報:「関数」は連携するインターフェースの集まりです。これはもともとUSB仕様の一部ではなかったので、どのインターフェイスを一緒にグループ化する必要があるかを決定することはデバイスドライバに委ねられました。 USBワークグループは、機能をサポートするデバイスクラスを定義します。これはインターフェース接続記述子(IAD)を介して行われます。

おすすめ記事