PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 |
2011.7.10 前へ 次へ 目次へ戻る ホームページトップへ戻る |
☆USB(HIDクラス) USBを通じてパソコンとの間でデータを送受信する方法にいくつかの種類があることがわかりました。 その中で特別のドライバをインストールする必要のないHIDクラスを使うことを考えます。 |
[第36回]
●インタラプト転送の「速度」
HIDでは、データの転送には、主として「インタラプト転送」を使う、ということがわかりました([第32回])。
インタラプト転送とは、あらかじめ決められた時間間隔(1ms〜255msの範囲で1msきざみ)で、定期的にデータを転送する方法です。
したがって、インタラプト転送で最も短い転送間隔は1msごと、ということになります。
では、1msごとになら、どれだけたくさんのデータでも送ることができるのか、といいますと、そうはいかなくて、1度に送信できるのは、最大64バイトということになっているらしいのです(?)。
はて、そんなことがどこに書いてありましたっけ?
USBで送受信されるデータは、トランザクションという、1つのまとまりとして送られるのですが、そのトランザクションはトークン、データ、ハンドシェイクという3つのパケットから構成されています([第32回])。
インタラプト転送では、このデータパケットには最大64バイトしか、のせることができません([第31回])。
そのトランザクションは、1msに1回ホストが発行するフレームという「枠」に入れられて、送られます([第32回])。
ここで扱うUSBのデータ転送クロックは12MHzです。
その12MHzのクロックがそのままビットレートになりますから、フレームにのせられる情報量は最大12000ビット(1500バイト)になります。
すると、データトランザクションがデータパケット以外に、トークンパケット、ハンドシェイクパケットからも構成されているとしても、その中核にあるデータパケットのサイズはたかだか64バイト(512ビット)ですから、もしも送信するデータが64バイト以上あったなら、そしてもしもパソコンにはターゲット以外のUSB装置がつながっていなかったならば、同じフレームに複数のデータトランザクションが「連続して」入れられるのではないだろうか、という当然の疑問がでてきます。
うう。「連続して入れられる、などと考えちゃダメよ」って、書いてありましたねぇ([第35回])。
んでも、こんな表をみつけてしまうと、ほらできるじゃないの、と思わず言ってしまいたくなります。
[出典]Universal Serial Bus Specification(Revision2.0)
これは、フルスピード(12MHz)のインタラプト転送で、データパケットのサイズが1、2、4、…、64バイトであるときの、計算上の最大転送データ量(バイト/秒)と、そのときのデータトランザクション数(/フレーム)などを示したものです。
この表によると、最下行の64バイト/データパケットの場合、1フレームには最大19個のデータトランザクションを入れることができ、その場合1フレーム全体で運ぶことができるデータは64×19=1216バイトになる、とあります(ほら、しっかり詰め込んでいるじゃないの!)。
したがって、1秒間には1000フレームが送られるので、その間に送ることのできる最大のデータ量は、1216KBになる、ということが示されています。
一番下のMaxというのは、フレーム全体の情報量(データトランザクションだけではなくて、SOFもトークンもハンドシェイクも全部を含めたバイト量)を示しています。
12MHzですから12Mビット/秒です。それをバイトに換算すると、12000000/8=1500000バイト/秒になります。1フレームはその1/1000ですから、1500バイトになります。
1500バイトのうちデータ本体が占めることができるのは1216バイトで残りはロスということになります。
それなら、1216バイトまでのデータなら、1フレームで送れるじゃありませんか!
でも、んなわけはない、のですよねぇ(多分ですけれど…)。
はて、ではこの表の意味するところは、なんなのでしょう。
そもそも、一体HIDは1フレームに複数のトランザクションをのせることができるのか、はたまたできないのか。
うう。そこが問題です。
●やっぱりHIDは64バイト/フレームでした
こんなところにはっきり書いてありました。
[出典]USB Device Class Definition for Human Interface Devices(HID) Version 1.11
英語というのは、こういうところが実にはっきりしてるのですよねえ。
a transaction every USB frameと書いてあって、しっかりと ’a’ がついています。
やっぱりHIDの場合、1フレームに1トランザクションしかのせられないようです。
その点については、「これにて一件落着」ということになったわけなのですが…。
するとさきほどの表は、一体なんなのだ?
ひょっとするとHIDでは、インタラプト転送は1フレームに1トランザクションしか許されないが、HID以外のクラスなら、インタラプト転送でも、1フレームに複数のトランザクションをのせることが許されるのではないか?
で、またまた調べてみました。
●HID以外のクラスでも同じでした
NECのホームページ(http://www.necel.com/index_j.html)の製品情報の中に、
USBホームというページ(http://www.necel.com/usb/ja/about_usb/USB2_6.html)があって、そこでこんな説明をみつけました。
USB1.xでは一つのエンドポイントに対するInterruptまたはIsochronous転送は1
フレームに1回以上は行えませんでしたが、USB2.0では一つのエンドポイントに対するInterruptまたはIsochronous転送は1
マイクロフレームに3回までの転送が許されます。
この説明によれば、やっぱりインタラプト転送は、「USB1.xでは」1つのエンドポイントに対しては、1フレームに1トランザクションしか許されない、とのことです。
それでは、USB2.0ではどうなのか?といいますと。
USB2.0では3回まで許されるようになった、と書いてありますけれど、ただし、それは「マイクロフレームの場合には」、です。
マイクロフレームというのはハイスピードモード(480MHz)でのフレームですから、フルスピード(12MHz)には関係のない話です。
文脈からすると、USB2.0になっても、フルスピード(12MHz)のインタラプト転送は、HIDであろうとなかろうと、やっぱり1フレームあたり1トランザクションということのようです。
さて、すると、さきほどの表の意味は、なんなのか?
ということなのですが、このNECのホームページにあった説明文がヒントになりました。
あの表の意味は、1つのエンドポイントに対するインタラプト転送の最大転送量ではなくて、複数のエンドポイントに対するインタラプト転送が「多重」に行われるときの、最大転送量を計算したものだったのです(と思います)。
そうか。システム設計者には、そういう情報も必要かもしれませんね。
私の場合、あの表の数字はまったく利用する意味のないものでした。
結局、これまででわかったことは、HIDの場合(実はHIDでなくても、インタラプト転送の場合には)、最大データ転送速度は、64KB/秒ということです。
この数字は、もっと前から何回か書いていたものでしたが、あちこちのサイトでいろいろ読んでいるうちに、どうもそういうことらしい、ということで書いていたものを、今回は資料によってはっきりと確認できたことになります(やっとウラがとれました)。
CPUをつくろう!第428回(2010.2.2upload)を再編集
PICでUSBを![第36回]
2011.7.10upload
前へ
次へ
目次へ戻る
ホームページトップへ戻る