PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.7.10

前へ
次へ
目次へ戻る
ホームページトップへ戻る
☆USB(HIDクラス)

USBを通じてパソコンとの間でデータを送受信する方法にいくつかの種類があることがわかりました。
その中で特別のドライバをインストールする必要のないHIDクラスを使うことを考えます。

[第35回]

●パイプとフレームとトランザクション(どのような関係なのか?)

前回までのところで、USBでデータを送受信するときは、トランザクションという「組」が単位になって行われる、という説明をしました。
USB通信での信号の最小の構成単位(構成要素)はパケットです。

トランザクションは、トークンパケットとデータパケットとハンドシェイクパケットから構成されます。
トークンパケットはこれからデータを送出するか、またはデータを読み込むか、ということを、端末に伝えるために、ホスト(パソコン)から出力されます。
次のデータパケットは、データを含む中核になるパケットです。
OUTトランザクションのときは、トークンパケットに続いてホストからデータパケットが出力されますが、INトランザクションでは、トークンパケットの出力によって指定された端末から、ホストに向けてデータパケットが出力されます。
最後のハンドシェイクパケットはデータが正しく受信されたかどうかを、受信側から送信側に向けて出力されます。
受信が成功したときはACKが、失敗したときはNAKが返されます。
OUTトランザクションでは、ホストがデータパケットを出力しますから、ハンドシェイクパケットは端末側が出力します。
INトランザクションは、端末がデータパケットを出力しますから、ハンドシェイクパケットはホストが出力します。

このトランザクションはUSB信号として、勝手に送られるのではなくて、フレームというまとまりの中で送られます。
フレームは1msごとにSOF(Start Of Frame)パケットによって開始されます。
フレームの終わり(EOF。End Of Frame)もあるのですが、こちらはパケットではなくて、特殊な信号パルスになっています。

トランザクション(おもにデータトランザクション)は、その1msごとのフレームに乗せられるかたちで運ばれます。

ところで、今度は、そのフレームとパイプはどのような関係になるのか、ということについて考えてみたいと思います。
データはトランザクション(データトランザクション)という形にまとめられて、フレームに乗せられて運ばれる、ということを説明しました。
フレームは1msごとに送られます。
そして、HIDのインタラプトデータ転送の場合、1つのデータトランザクションには最大でも64バイトのデータしか入れられません、ということも、前に説明をしました。
一方で、ホストとUSB端末とは、パイプという仮想的な伝送路を使って、データトランザクションを送る、というようにも説明をしました。
そうすると、いったいフレームとパイプとはどのような関係になるのでしょうか。

あまりよいたとえではないかも知れませんが。
駅のホームで電車を待つ人の列を考えてみたらどうでしょうか。
その列がパイプの送信側部分に相当します。
並んでいる人がトランザクションです。
電車がフレームということになります。
ホームで待っているひとの行列は何本もありますが、同じ電車に乗り込みます。
満員で乗れなくなったら、残りのひとは次の電車がくるのを待ちます。

だいたいそんなイメージになると思います。
で、むこうの駅についたら、降りた人はまた列になって、複数の出口に向かいます。

ただ、この例ではUSBの通信をうまく説明できないところがあります。
この電車の例では、「トランザクション」は上り(IN)か、下り(OUT)の電車に乗って、相手側(到着駅)に向かう、というイメージになりますが、実際のUSB通信では、上り(IN)、下り(OUT)の電車に乗って運ばれるのは、トランザクションの中の「データパケット」だけで、INトークンパケットはデータパケットと逆向きに運ばれますし、ハンドシェイクパケットは必ずデータパケットとは逆向きになります。
データトランザクションを考えるときには、そのデータが送られる向きにトランザクション全体が送られるかのように、説明もなされますが、実際には、そのトランザクションを構成するトークンパケットとハンドシェイクパケットは、データパケットと同じ向きに運ばれるとは限らない、ということを理解しておいてください。

OUTトランザクションの場合は、トークン(OUT)、データトランザクション(OUT)、ハンドシェイク(IN)という向きになります。
INトランザクションの場合は、トークン(OUT)、データトランザクション(IN)、ハンドシェイク(OUT)という向きになります。
IN、OUTはホストがデータを入力する(IN)、ホストがデータを出力する(OUT)という向きであることを示しています。

さて、では、そのパイプから1msごとに送られるフレームに、どのようにデータトランザクションが乗せられるのか、ということについてはどうでしょうか。
私は当初は、もしもUSB装置がただ1つだけしか、パソコンに接続されていなかった場合には、この1msのフレームに乗せられるだけのトランザクションが「つめ込まれて」送られる、というように解釈していました。
あるいはバルク転送についてはそういうことかもしれません。
私はHIDを使うことに決めてしまいましたから、バルク転送については、詳しくは調べていませんから、そこのところはよくわかりません。
少なくともHIDについては、他にUSB装置がつながっていない場合にも、1つのフレームには1つのデータトランザクションしかのせられないようです。
HIDでは普通のデータ転送は、インタラプト転送というモードで行われます。
インタラプト転送とは、決められた時間間隔毎にデータを転送する方式で、その時間間隔は1ms〜255msの範囲で、1msごとに決められますから、最小の時間間隔を選択しても1msに1回の送信しかできないことになります。
データが64バイト以上ある場合には、それを64バイトごとに分割して、「連続して」同じフレームにのせて送信できる、と考えてもよさそうに思えたのですが、あくまで一度には1つのトランザクション(最大64バイト)しか送れない、ということのようです。

まあ、HIDの場合にはそういうことですので、複数のトランザクションに分割されたデータが、どのような順序でフレームに乗せられるのか、ということは、考えても意味がない、ことになりますが、たまたまこんな説明をみつけてしまいましたので、そのコピーをお見せすることにいたします。


[出典]Universal Serial Bus Specification(Revision2.0)(赤アンダーラインは筆者)

ちょっとわかりにくい文章です。個々に直訳しようとすると、考えてしまいますが、いわんとするところはわかるような気がします。
図では2つのパイプ(パイプ1とパイプ2)があって、それぞれトランザクション1−0、1−1、1−2とトランザクション2−0、2−1、2−2がその「順番」で送られるのを待っています。
HOSTのUSBコントローラは、これをどのような順番でさばくのか、という説明です。
うーん。ちょっと、訳し方が間違っているかも知れませんが。
読んでみると、なかなか面白い表現だなあ、と思います。

ホストコントローラは、それをどうさばこうと勝手(are free)だとおっしゃっているようです。
ま、そりゃそうでしょう。
それぞれのデータがどのようにさばかれようと、要は送った順番の通りに相手側に届きさえすればそれでよいのですから。
あ。それについては、そのとおりである、と書いてあります(an endpoint will see transactions in the order they appear within an IRP unless errors occur.)。
IRPとはI/O Request Pipe、つまりINパイプ、OUTパイプのことです。

で、図の説明です。
たとえば1番目のパイプの最初のトランザクションを最初のフレームのどこかに置いて、それに続いて2番目のパイプの最初のトランザクションを置いたとしても、その次には、それとは逆の順序で、次のフレームのどこかに、1番目のパイプの2番目のトランザクションを、2番目のパイプの2番目のトランザクションの次に置いても、それはホストコントローラが勝手に決めることである(a Host controller is free to move)、だそうです。

さて、赤アンダーラインの部分です。ここはどう訳したらよいのでしょうかねぇ。
なんだかむつかしいです。

パイプで連続している(back−to−back)トランザクションが、フレームでもその通りになっている、などという考えに基づいたプログラムはできっこないし、また、トランザクションがフレームの中で連続している、ということようなことを考えてプログラムを作ったりしたら、ダメだからね。

というようなことになりますでしょうか。

うーん。
確かに、HIDについてのテストをいろいろやってきただけですけれど、フレームの中の状態はかなりいい加減というか、むむ、コントローラ様がけっこう自由に振舞われていらっしゃるなぁ(どういう理由でそのようになるのかはわかりませんけれど)、という印象ではありますねえ。
CPUをつくろう!第427回(2010.2.1upload)を再編集

PICでUSBを![第35回]
2011.7.10upload

前へ
次へ
目次へ戻る
ホームページトップへ戻る