一般に、1台のパソコンが親機となって、接続しているマウスやキーボードの子機側と通信をします。
親機をホスト(Host またはルートノード)、子機をノード(Node またはターゲット)と呼んでいます。
ノードには「デバイス」と「ハブデバイス」(ハブと呼ぶ)があります。
ハブの従属接続は、全体で5段までと制限され、各機器間も5m以内になっています。
ハブとデバイスすべてにアドレスが付加されて管理されます。
このアドレスが最大127個なので、接続可能なデバイスは最大127台ということになります。(ルートハブはアドレスが不要)
USB1.0(最大12 Mbps)→USB 1.1→USB 2.0(High-Speedモード最大480 Mbps)→USB 3.0→USB 3.1(SuperSpeedPlus USBで10Gbps)→USB 3.2とバージョンアップしてきました。
接続コネクタも、たくさんの種類があります。(ありすぎる)
最初は、USBタイプAとタイプBでした。
USBはAがホスト用、Bがデバイス用になっています。
その後、デジタルカメラなどのためにmini-USBが作られました。
当初はAタイプで、1000回抜き差し寿命で、その後には5000回の抜き差しに耐えうるmini-USBのBタイプが作られました。
それにより、A・Bどちらにも対応したマルチ差込口が流行り、Aは使われなくなりました。
よって、mini-USBは基本的にBのことだと考えてもらって構わないほどです。
さて、携帯電話などが普及で、「5000回抜き差し寿命」を改善のためmicroUSBが開発されました。
1万回の抜き差しに耐え、しかも小さく、その上コストも安い優れモノで、mini-USBは廃れていきます。
microUSBは当初、ホスト用のA、デバイス用にBが使われていましたが、スマートフォンの出現でデバイス用としてPCに繋げるが、
ホスト用としてUSBメモリを接続したい要求が生じました。
これで「AもBもどっちも挿せるマルチ差込口対応」になり、最終的に、「全部Bで」と変化してきています。
この時、搭載機器をホストとして動作せたい場合に使用するOTG(On-The-Go )の規格が使われ始めています。
なお、appleではUSB規格を逸脱して、Lightning(ライトニング)USBが登場させています。
リバーシブル構造で充電や電力の供給に優れるiPhoneのappleが独自規格です。
一方USBの方でも、最も新しいUSBとして『Type-C』を登場させいます(2017年7月)
これはUSBでありながらLightningUSBのようにリバーシブルな接続を可能として、速度も速い(20Gbps)という最新鋭の規格です。
動画も転送できるため、データ転送に『USB』、テレビへの動画再生で、電源供給が『Type-C』ひとつで実現できます。
基本的にホストからの命令がないとデバイス側は何もしません。
構造的には、物理層の上にシステムソフトウェア(デバイスドライバ)があり、その上にアプリケーションソフトが載る構造です。
ホストとデバイス間では、「FIFO バッファ」を使う「パイプ」と呼ぶ論理的な接続を使って通信します。
「FIFO バッファ」は、「エンドポイント」と呼ぶ概念で表現されます。
(ランダム・アクセスが可能なバッファのエンドポイントも存在します)
最初はシステムソフトウェアで「コンフィギュレーション」と呼ばれる通信を行いす。
これは、パイプの本数や、転送モードなどの設定情報をホストがデバイスに要求し、その応答を元にしてホストがデバイスの使用条件を設定します。
この送受信は双方向になっています。
アプリケーションのレベルの通信は、片方向だけの通信で、
ホストから転送する「OUT」と呼ばれるパイプと、デバイス側から転送する「IN」と呼ばれるパイプがあります。
「コンフィギュレーション」や「OUT」、「IN」は「コントロール転送」で制御され、それを司るのが「エンドポイント0(FIFO0)」となります。
まずコントロール転送を使って、コンフィギュレーションを実行し、デバイスの使い方が設定され、
その時に、コントロール転送以外のあらたな「OUT」、「IN」などのエンドポイントが追加され、パイプが構成されます。
このパイプの番号とエンドポイントの番号はホストが指定します。
パイプの通信の仕方には、「コントロール転送」を加えて「バルク転送」、「インタラプト転送」、「アイソクロナス転送」があり、
それぞれ異なる特徴になっています。
どれを使うかは、予めデバイス側でコンフィギュレーション用のデータとして持っており、USB を接続した時にコントロール転送を使ってホストにその情報を渡し、
それを元に、ホストでモードが確定します。
この時ホスト側から、デバイスのアドレス付けと、パイプ番号とエンドポイント番号の割り付けが行われます。
物理層の実際のデータは、「フレーム」と呼ばれる単位で通信されています。このフレームはある 周期(フル・スピードでは1ms,ハイ・スピードでは125μs)で繰り返し転送されています。
これを制御してパイプという論理的データとしてアクセスできるようにすることがシステムソフトウェアの役割です。
「フレーム」は「SOF(Start of Frame)」と呼ばれる「パケット」で始まる複数の「トランザクション」と呼ぶ構造の「パケット」の集合で構成されます。
つまり、一つのフレームは、次の構造です。
『[SOFのパケット][Transactionのパケット][Transactionのパケット]・・・・』 これが1つ分で、ある 周期で繰り返し転送される
(TransactionのパケットはSETUP, OUT, IN の3種類で、データ領域の長さは設定により異なる。各パケット内の最後にACKがある。)
下記「トランザクション」の「パケット」で、表記部分がホスト側の送信を意味します。
SETUP DATA0 ACK
OUT DATA0/1 ACK
IN DATA0/1 ACK
なお、「SOFパケット」、「トランザクションパケット」の内部は、かならず同期をとるため先頭に[SYNC(8bit)]があり、
続けてパケットの種別を表す[PID(8bit)]が存在する。(PIDは実質4bitで、残り4bitは前述4bit列を反転させた並びになっている)
(パケットで分類すると、SOFパケット、トークンパケット、データパケット、ハンドシェイクパケットがあります。)
「SOF(Start Of Frame)パケット」[SYNC:8bit][PID:8bit][Frame番号:11bit][CRC:5bit]
Frame番号は 0H〜7FFH
「トークンパケット」[SYNC:8bit][PID:8bit][Device Address:7bit][End Point][CRC:5bit]
Device Addressは 0H〜7FH、ENDPは0H〜FH
「データパケット」[SYNC:8bit][PID:8bit][0〜1023byteのバイト単位データ][CRC:16bit]
「ハンドシェイクパケット」[SYNC:8bit][PID:8bit]
PIDの4bitは各パケットで次のように決まっている。
パケットの種類 | PIDの名称 | 意味 | 4bit |
---|---|---|---|
Start Of Frameパケット | SOF | フレーム開始 | 0101 |
トークンパケット | OUT | エンドポイントへの転送 | 0001 |
IN | ホストへの転送 | 1001 | |
SETUP | セットアップ | 1101 | |
データパケット | DATA0 | データ | 0011 |
DATA1 | データ | 1011 | |
ハンドシェイクパケット | ACK | データ正常受信 | 0010 |
NAK | データ転送不成功 | 1010 | |
STALL | エンドポイントのストール | 1110 | |
スペシャル | PRE | ロースピード転送許可 | 1100 |
USBはホストの電源をON にしたままデバイスの接続や、切り離しが可能で「プラグ&プレイ機能」と呼ばれます。
これは、接続された時点で自動的に必要なドライバソフトを探し、適当なものを起動して使えるようにしています。
これを可能にするにはホスト側とデバイス側のプログラムの連係で可能になります。
これは次の手続きで実現されます。
(1) USB ケーブルの接続(アタッチ)
この検出はD+かD-いずれかが3.3V という状態になることで検出します。
従って、デバイス側の電源の供給方法によって、少し動作が異なります。
バスパワーのアタッチは、接続と同時に検出されることになります。
対してセルフパワーのアタッチは、デバイスの電源ON 状態で検知されます。
(2) RESET
ホスト側がアタッチを検知すると、一定時間以上のRESET 状態を出力します。
これは、D+,D-の両方をLow にします。
それによりデバイス側はRESET と感知(いつでも検出可能になっている)して内部リセットを実行しします。
内部リセット後は、Default状態に戻ります。
(このDefault状態では、パイプ0を使ったコントロール転送が可能な状態です)
(3) コンフィギュレーション
ホスト側はRESET を出力したあと、コンフィギュレーションに移行します。
具体的には、まずホストから「Get_Configuration」を転送し、データを返送を要求します。
つまり、デバイス内に保持している、「デバイスディスクリプタ」の情報の転送を要求します。
これに対し、デバイス側から「Configuration」のデータを返送します。
次にホストは、このデバイスに対して、使われていないアドレスにセットアップするよう、デバイスに「Set_Address」を転送します。
これでデバイスが特定のアドレスを持ったことになります。
以降はこのデバイスアドレスで通信を行います。
このあと、再度ホストからディスクリプタの詳細情報を要求し、デバイスは、必要な情報を返送します。
この中には、デバイスのリソースに関する情報が含まれており、パイプの使い方や、ID コードが送られます。
ホスト側は、このID コードを元にドライバを探し、適当なものを起動します。
はじめて接続検出したID の場合には、ドライバのリンクの手順に進みます。
ドライバのリンクが完了した時点で、ホストから「Set_Configuration」を送信して改めてデバイスのコンフィギュレーシ
ョンをやり直して完了となります。
以降は、コンフィギュレートした内容に基づいて通信が行われることになります。