USB デバイスストレージクラス
USB
デバイスストレージクラスにより、システムに埋め込まれたストレージデバイスがUSB
ホストに 可視になります。USB
デバイスストレージクラスは、それ自体でストレージソリューションを提供するものではありませ ん。単にホストからのSCSI
要求を受け付け、解釈するだけです。その要求の1
つが読み出しコマン ドまたは書き込みコマンドのときは、ATA デバイスドライバ、フラッシュデバイスドライバなど、実スト レージデバイスハンドラへの定義済みのコールバックを呼び出します。デバイスストレージクラスを初期化するときに、必要なすべての情報を含むクラスにポインタ構造が 与えられます。例を次に示します。
/* Store the number of LUN in this device storage instance: single LUN.*/
storage_parameter.ux_slave_class_storage_parameter_number_lun = 1;
/* Initialize the storage class parameters for reading/writing to the Flash Disk.
*/
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_last_lba = 0x1e6bfe;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_block_length = 512;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_type = 0;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_removable_flag = 0x80;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_read = tx_demo_thread_flash_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_write = tx_demo_thread_flash_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_status = tx_demo_thread_flash_media_status;
/* Initialize the device storage class.The class is connected with interface 0
*/
status =
ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry, ux_device_class_storage_thread, 0, (VOID
*)&storage_parameter);
この例では、ドライブの
LBA(最後のブロックアドレス)、それに論理セクタサイズが与えられます。
LBA
は、media –1
において使用可能なセクタ数数です。ブロック長は、正規のストレージ媒体内で512
に設定されます。光学ドライブの場合は、2048
に設定できます。ストレージクラスが媒体のステータスを読み出し、書き込み、および取得できるように、アプリケーショ ンは
3
つのコールバックファンクションポインタを渡す必要があります。読み出し用と書き込み用のファンクションのプロトタイプは次の通りです。
UINT media_read(UCHAR_PTR data_pointer, ULONG number_blocks, ULONG lba);
UINT media_write(UCHAR_PTR data_pointer, ULONG number_blocks, ULONG lba);
ここで、
data_pointer
は 、 読 み 出 し ま た は 書 き 込 み に 使 用 す る バ ッ フ ァ の ア ド レ ス 、number_blocks
は、読み出し/書き込み対象のセクタの数、lbaは、読み出すセクタアドレスです。
返却値は
UX_SUCCESS、UX_ERROR
のいずれかで、操作に成功したか失敗したかを示します。これらの操作で、その他のエラーコードを返す必要はありません。操作にエラーがある場合は、スト レージクラスがステータスコールバックファンクションを呼び出します。
このファンクションのプロトタイプは次の通りです。
ULONG tx_demo_thread_media_status(ULONG media_id);
呼び出しパラメータ
media_id
は、現在使用されていないため、常に0
に設定しておきます。将来は、複数ストレージデバイスを区別するため、あるいは複数
SCSI LUN
を持つストレージデバイスを区別 するために、media_id が使用される可能性があります。このバージョンのストレージクラスでは、スト レージクラスの複数インスタンスや、複数SCSI LUN
を持つストレージデバイスをサポートしていませ ん。返却値は
SCSI
エラーコードです。これは次のようなフォーマットにすることができます。ビット
0
~7 Sense_key
ビット
8~15
追加センスコード(Additional Sense Code: ASC)ビット
16~23
追加センスコード修飾子(Additional Sense Code Qualifier: ASCQ)可能な
Sense/ASC/ASCQ
の組み合わせを次の表にまとめます。Sense Key
ASC ASCQ 説明
00 00 00 検知なし
01 17 01 再試行によって読み取れたデータ 01 18 00 ECCを使って読み取れたデータ
02 04 01 論理ドライブが動作不可能。動作可能にする処理中 02 04 02 論理ドライブが動作不可能。初期化が必要
02 04 04 論理ユニットが動作不可能。フォーマット中 02 04 FF 論理ドライブが動作不可能。デバイスがBUSY
02 06 00 参照位置を検出せず 02 08 00 論理ユニットの通信の故障 02 08 01 論理ユニットの通信のタイムアウト 02 08 80 論理ユニットの通信のオーバーラン 02 3A 00 媒体未装着
02 54 00 USBとホストシステムとの間のインタフェース故障 02 80 00 リソース不足
02 FF FF 不明なエラー 03 02 00 シーク完了せず 03 03 00 書き込み障害
03 10 00 ID CRCエラー
03 11 00 回復不可能読み出しエラー
03 12 00 IDフィールドのアドレスマーク検出せず 03 13 00 データフィールドのアドレスマーク検出せず 03 14 00 レコード実体検出せず
03 30 01 未知フォーマットのため読み出し不可能 03 31 01 フォーマットコマンド失敗
04 40 NN 診断で構成要素NNに故障(80H-FFH)
05 1A 00 パラメータリスト長エラー 05 20 00 コマンドの操作コードが不正 05 21 00 論理ブロックアドレスが範囲外 05 24 00 コマンドパケットのフィールドが不正 05 25 00 論理ユニットがサポートされていない 05 26 00 パラメータリストのフィールドが不正 05 26 01 パラメータがサポートされていない 05 26 02 パラメータ値が不正
05 39 00 パラメータ保存機能なし
06 28 00 動作不可能状態から動作可能状態への遷移あり。媒体が交換された 06 29 00 電源投入、リセットまたはバスデバイスリセットが発生
06 2F 00 他のイニシエータによりコマンドが消去 07 27 00 書き込み保護媒体
0B 4E 00 コマンド重複
複数 SCSI LUN
USBX
デバイスストレージクラスは、複数のLUN
をサポートします。したがって、CD-ROM とフラッ シュディスクを同時に兼任するストレージデバイスを作成できます。その場合、初期化は若干違った ものになります。以下は、フラッシュディスクとCD-ROM
の場合の例です。/* Store the number of LUN in this device storage instance. */
storage_parameter.ux_slave_class_storage_parameter_number_lun = 2;
/* Initialize the storage class parameters for reading/writing to the Flash Disk. */
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_last_lba = 0x7bbff;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_block_length = 512;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_type = 0;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_removable_flag = 0x80;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_read = tx_demo_thread_flash_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_write = tx_demo_thread_flash_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_status = tx_demo_thread_flash_media_status;
/* Initialize the storage class LUN parameters for reading/writing to the CD-ROM. */
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_last_lba = 0x04caaf;
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_block_length = 2048;
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_type = 5;
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_removable_flag = 0x80;
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_read = tx_demo_thread_cdrom_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_write = tx_demo_thread_cdrom_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[1].
ux_slave_class_storage_media_status = tx_demo_thread_cdrom_media_status;
/* Initialize the device storage class for a Flash disk and CD-ROM.The class is connected with interface 0 */
status =
ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry, ux_device_class_storage_thread,0, (VOID *) &storage_parameter);
USB デバイス CDC-ACM クラス
USB
デバイスCDC-ACM
クラスを使用すると、USB ホストシステムが、通信相手のデバイスをシリアルデバイスとして扱うことができます。このクラスは
USB
規格に基づいていて、CDC 規格のサブ セットとなっています。CDC-ACM
準拠のデバイスフレームワークは、デバイススタックが宣言する必要があります。例を次に示します。
unsigned char device_framework_full_speed[] = { /* Device descriptor 18 bytes
0x02 bDeviceClass: CDC class code 0x00 bDeviceSubclass: CDC class sub code 0x00 bDeviceProtocol: CDC Device protocol
idVendor & idProduct - http://www.linux-usb.org/usb.ids
*/
0x12, 0x01, 0x10, 0x01, 0xEF, 0x02, 0x01, 0x08, 0x84, 0x84, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
/* Configuration 1 descriptor 9 bytes */
0x09, 0x02, 0x4b, 0x00, 0x02, 0x01, 0x00,0x40, 0x00,
/* Interface association descriptor.8 bytes. */
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
/* Communication Class Interface Descriptor Requirement.9 bytes. */
0x09, 0x04, 0x00, 0x00,0x01,0x02, 0x02, 0x01, 0x00,
/* Header Functional Descriptor 5 bytes */
0x05, 0x24, 0x00,0x10, 0x01,
/* ACM Functional Descriptor 4 bytes */
0x04, 0x24, 0x02,0x0f,
/* Union Functional Descriptor 5 bytes */
0x05, 0x24, 0x06, 0x00, /* Master interface */
0x01, /* Slave interface */
/* Call Management Functional Descriptor 5 bytes */
0x05, 0x24, 0x01,0x03, 0x01, /* Data interface
*/
/* Endpoint 1 descriptor 7 bytes */
0x07, 0x05, 0x83, 0x03,0x08, 0x00, 0xFF,
/* Data Class Interface Descriptor Requirement 9 bytes */
0x09, 0x04, 0x01, 0x00, 0x02,0x0A, 0x00, 0x00, 0x00,
/* First alternate setting Endpoint 1 descriptor 7 bytes */
0x07, 0x05, 0x02,0x02,0x40, 0x00,0x00,
/* Endpoint 2 descriptor 7 bytes */
0x07, 0x05, 0x81,0x02,0x40, 0x00, 0x00,
CDC-ACM
クラスでは、複合デバイスフレームワークを使用してインタフェース群(制御インタフェースとデータインタフェース)をグループ化します。したがって、デバイス記述子を定義するときに注意 が必要です。インタフェースをどのようにバインドするかについて、
USBX
はIAD
記述子から知ること になります。IAD 記述子は、インタフェースの前に宣言される必要があり、CDC-ACM クラスの最初 のインタフェースについて、またアタッチされているインタフェースの数を記述する必要があります。CDC-ACM
クラスでは共用体ファンクショナル記述子(union functional descriptor)も使用しますが、これはより新しい
IAD
記述子と同じファンクションを実行するものです。共用体ファンクショナル記述 子は、歴史的経緯から、またホスト側と互換性を取るために宣言される必要がありますが、USBX
で は使用されません。CDC-ACM
クラスの初期化には以下のパラメータが必要です。/* Set the parameters for callback when insertion/extraction of a CDC device. */
parameter.ux_slave_class_cdc_acm_instance_activate =
tx_demo_cdc_instance_activate;
parameter.ux_slave_class_cdc_acm_instance_deactivate =
tx_demo_cdc_instance_deactivate;
/* Initialize the device cdc class.This class owns both interfaces starting with 0.*/
status =
ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry, 1,0, ¶meter);
ここで定義している
2
つのパラメータは、スタックがこのクラスをアクティブ/非アクティブ化するとき にコールされる、ユーザアプリケーションへのコールバックポインタです。CDC-ACM
は、USB-IF
規格を基にしていて、MAC OS
やLinux
オペレーティングシステムで自動的に認識されます。Windowsプラットフォーム上では、このクラス用に.infファイルが必要です。
ExpressLogic
社 で はCDC-ACM
ク ラ ス の テ ン プ レ ー ト を 提 供 し て い ま す が 、 こ れ はusbx_windows_host_files
ディレクトリに収めてあります。Windows
の最近のバージョンでは、ファイル
CDC_ACM_Template_Win7_64bit.inf
を使用する必要があります。このファイルは、デバイスで使用する
PID/VID
を反映するように修正する必要があります。企業と製品をUSB-IF
に登録した時点で、PID/VIDは最終カスタマに固有になります。
inf
ファイル内で修正が必要なフィールドは、以下の場所にあります。[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_8484&PID_0000 [DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_8484&PID_0000