[Top] | [Contents] | [Index] | [ ? ] |
Copyright © 2010 K. Dobashi.
1. USB-RS232Cコンバーターを使ってLinuxから複数のシリアルデバイスを制御する | ||
Index | Complete index. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
シリアル通信(RS232C)は、その規格の陳腐さにも係わらず、未だに標準的なインターフェースとして用いられています。RS232Cポートを装備した機器は未だに多く存在します。
一方で、最近はUniversal Serial Bus(USB)も用いられるようになりました。しかしながら、USB機器の場合、その機器に適合したUSBデバイスドライバがないど動作しません。USBデバイスが市販されている場合、Windows用のドライバは大抵添付されているか、何らかの方法で入手可能です。しかし、Linuxの場合USBデバイスドライバが提供されていない場合も多いのが現状です。
幸いにも、Linux版のUSBデバイスドライバがある場合はそれを用いることで機器をコントロールできるかもしれません。また、USBデバイスドライバがなくても、その機器にRS232CポートがあればRS232Cで機器をコントロールすることができるでしょう。
しかし、RS232Cはレガシーなインターフェースであり、最近のPCにはRS232Cのポートが具備されていない場合も多くなっています。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
RS232CポートのないPCが増えつつあるなかで、RS232C機器を使いたいという要求も多く、そういった状況のなかで、USB-Seriac(RS232C)コンバーターが製造販売されています。
これは、RS232Cポートを具備したUSBデバイスで、ソフトウェア側からは接続された機器がRS232Cシリアルポートのように見えるというものです。
USBの規格では、1つのバスに最大で127台の周辺機器を接続することができ、USB-Serialコンバーターを用いることで原理的にはシリアルデバイスを127台接続することが可能になります。
しかし、複数のUSBデバイスを接続する場合には問題があります。
一番の問題は、同じ種類のUSBデバイスを複数接続した場合に、どうやってソフトウェア側からそれぞれの個体を識別するかということです。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
USBデバイスには製造メーカーをあらわす「ベンダーID」(16bit)と製品種別を表す「プロダクトID」(16bit)が割り振られています。また、1台1台ユニークなIDとして「iSerialNumber」(シリアル番号)という文字列(16進16桁)が設定されている場合があります。(しかし、iSerialNumberが無いUSBデバイスもある)
ベンダーIDは、chipベンダーや最終製品ベンダーに割り振られるIDで、個人で取得することも可能なようです(http://www.usb.org/developers/vendor/)。プロダクトIDは、各製品付与するIDで、これはベンダーが勝手に決めて良いように思われます。特にFTDIのchipでは、EEPROMにベンダーIDの書き込みも可能のようです。が、できるだけFTDIのベンダーIDを使うのが望ましいとの情報もあります。
今回重要になるのは、iSerialNumberです、これは個々のデバイスに割り振られているものであり、個体をソフトウェア側から識別するのには必須です。
個々のデバイスを識別する方法としては、デバイスが接続されているバスやポート番号を調べる方法も考えられます。しかし、デバイスの抜き差しをした場合に番号が変わったり、電源再投入時に番号が変わってしまうことがあります。勿論、USBポートを増設するためなどで配線を変えると、番号が変わる可能性があり、混乱するのは必至です。
ここでは、Linux上でiSerialNumberを用いてUSB-Serialコンバーターの個体の識別を行うことを考えます。現在のLinuxディストリビューションにはudevという仕組みが用意されており、今回のような課題にはudevを適切に運用することにより解決できます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
USB-Serial(RS-232C)デバイスはいくつか発売されていますが、今回の目的のためにははいくつか条件があります。
当たり前ですが、ドライバーが無いと、認識すらされません。
個別のデバイスを認識するためには、デバイス自体にiSerialNumberが設定されていることが必要です。 もしくは、iSerialNumberの設定が可能でなければなりません。これは通常でデバイス内のEEPROMに書き込まれているようです。このEEPROMを書き換えるためのルールが用意されている場合(FTDIなど)もあります。
同じ種類のデバイスを1個だけ使用する場合には問題になりませんが、複数個になると、どれがどれか識別ができなくなります。個々にシリアル番号が設定されていれば、それを元に個々のデバイスを識別可能です。ですので、非常に重要です。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
USB-Serial(RS-232C)デバイスはかなりの種類が出回っていますが、それらは、幾つかのメーカーの USB-Serial用chipを利用しています。代表的なものは以下の通りです。
一番利用例が多いのがPL-2303(Prolific Technology Inc.)です(http://www.prolific.com.tw/eng/products.asp?id=59)。 価格が低いらしく、低価格の製品に多く使われているようです。
ですが、EEPROMの書き換えツールは配布されておらず、iSerialNumberの設定は事実上不可能です。
単体で用いる場合には問題ないですが、複数個の使用の場合には個々のデバイスの識別の点で支障が出てくると考えられます。ですので、あまりお薦めできません。
Linuxではpl2303ドライバーが存在します。
PL-2303を使用している(と思われる)製品は以下の通りです。
Future Technology Devices International, Ltd(http://www.ftdichip.com/)は、早くよりこの手のchipの開発を行っている会社だと聞き及んでいます。
FT232系のchipには、Linuxのドライバーとしてftdi_sioが用意されています。ですので、Linuxでも利用可能です。
また、FTDI社自らEEPROMの書き換えツールを無料で配布(2010年12月現在、http://www.ftdichip.com/Support/Utilities.htm#FT_Prog、Windows用)しています。これによiSerialNumberの書き換えが可能であるので、今回の目的には適していると考えられます。
ただし、このchipを採用している全ての製品がEEPROM書き換えに対応しているとは限らないので、確認が必要です。
EEPROMの書き換え可能を確認したのは、以下の製品です。
他にFT232系chipを使用している(と思われる)のは、
動作確認がとれていますので、SRC06USM SRC06USBをお薦めします。
Silicon Laboratories Inc.(http://www.silabs.com/Pages/default.aspx)は、競ってこの手のICを手がけているようです。CP2102、CP2103など幾つか種類があるようです(http://www.silabs.com/products/interface/usbtouart/Pages/default.aspx)。
詳しいことは分かりませんが、Linux用のドライバーはあるようです。 しかしながら、iSerialNumberが設定できるかどうかは不明です(試していないので)。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
usbデバイスが利用可能な状態であれば、lsusb
コマンドが有効に使えるかも知れません。
試しにlsusb
を実行してみましょう。root権限が必要かもしれません。
# lsusb Bus 001 Device 001: ID 0000:0000 Bus 001 Device 006: ID 05e3:0710 Genesys Logic, Inc. USB 2.0 33-in-1 Card Reader Bus 001 Device 004: ID 0411:0029 MelCo., Inc. Bus 002 Device 013: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC Bus 002 Device 001: ID 0000:0000 Bus 002 Device 003: ID 413c:3012 Dell Computer Corp. Optical Wheel Mouse Bus 002 Device 002: ID 413c:2003 Dell Computer Corp. Keyboard |
対象のデバイスを接続したり取り外したりしながらlsusb
で表示されるどのデバイスが対象デバイスであるか確認できると思います。ただし、同じ種類のデバイスを接続してしまうと、このあとの設定の時に混乱するので、目的のデバイスのみをPCに接続してみてください。
ここでは4番目のFT232 USB-Serialが対象です。0403:6001となっていますが、0403はベンダーID、6001はプロダクトIDのようです。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
より詳しい情報は、lsusb
に`-v'オプションを付けます。しかしこれでは全てのUSBデバイスに対して詳細が表示されますので、不都合です。対象のデバイスだけの詳細を表示させるため`-d'オプションを付加します。上記で表示されているIDを用いて以下のようにします。
#lsusb -v -d 0403:6001 Bus 002 Device 014: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0x6001 FT232 USB-Serial (UART) IC bcdDevice 4.00 iManufacturer 1 FTDI iProduct 2 USB HS SERIAL CONVERTER iSerial 3 OMEC-4BG bNumConfigurations 1 … |
出力はかなり長いですが、興味があるのは上記の部分です。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
iSerialにiSerialNumberが出力されています。iSerialNumberは`OMEC-4BG'であることがわかります。
iSerial 3 OMEC-4BG |
この部分が空白である場合は後述するudev.ruleの設定ができません。
そもそも
iSerial 0 |
となっている場合は、iSerialNumberの設定自体が不可能と思われます(IO DATAのUSBRSAQ3がそうでした)。
iSerial 3 |
の場合、カーネルドライバーの問題(Fedora13ではそうでした。CentoOS5.5ではiSerialNumberが表示されるにもかかわらず、Fedora13では表示されませんでした。)で表示されないか、またはiSerialNumberが設定されていないので、iSerialNumberを設定するなど適切に対処することが必要です。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
usb-serialコンバーターのためにudev.ruleを設定する
/dev/ttyUSB0
)指定して以下の通りにします。
# udevinfo -q path -n /dev/ttyUSB0 /class/tty/ttyUSB0 |
これで`/class/tty/ttyUSB0'を見れば良いとわかるので、
# udevinfo -a -p /class/tty/ttyUSB0 Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/class/tty/ttyUSB0': KERNEL=="ttyUSB0" SUBSYSTEM=="tty" ... |
色々と表示されます。 興味があるのは、iSerialNumberの部分です。
looking at parent device '/devices/pci0000:00/0000:00:02.0/usb2/2-5': ID=="2-5" BUS=="usb" DRIVER=="usb" SYSFS{latency_timer}=="16" SYSFS{configuration}=="" SYSFS{serial}=="OMEC-4BG" SYSFS{product}=="USB HS SERIAL CONVERTER" SYSFS{manufacturer}=="FTDI" SYSFS{maxchild}=="0" SYSFS{version}==" 1.10" |
lsusb
コマンドでもiSerialNumberは確認できますが、ここではudev.rulesに直接書き込めるフォーマットで出力されます。他にも色々表示されるので、必要ならそれをコピーするなどしておきます。
udev.rulesを適切に設定することで、個別のデバイスとデバイスファイルを関連づけることなどが可能になります。
ファイル名は、二桁の数字で始まり.rulesという拡張子で終わるようにします。最初の2桁の数字はあまり大きい数字にしない方が良いと思われます。udevは、`/etc/udev/rules.d/'の中の.fulesという拡張子のファイルを数字の順に見ようとするからです。先にシステムデフォルトの設定が呼ばれてしまうと、その設定でudevが動作します。後に読み込まれる設定は無視されます(場合によっては逆の場合もあります)。
最も簡単なudev.rules設定ファイルはおおよそ以下のようなものになると思います。 ファイル名は`/etc/udev/rules.d/51-usbserial.rules'です。
SUBSYSTEM=="tty", SYSFS{serial}=="OMEC-48G", SYMLINK+="ttyOMEC-4GB", MODE="0666" |
`SUBSYSTEM=="tty"'というのは、対象のデバイスがttyであることを示します。 `SYSFS{serial}=="OMEC-4BG"'は、対象のデバイスのiSerialNumberで、udevinfoで取得したものです。
上記の条件に当てはまるデバイスについて、以下の設定がなされます。
`SYMLINK+="ttyOMEC-4GB"'は、対象のデバイスのデバイスファイルのシンボリックリンクをttyOMEC-4GBという名前で生成することを示します。ファイル名として許される文字列であればどんなのでも構いませんが、それと判るものである方が無難です。今回はttyデバイスなので、頭にttyをつけてみました。
この設定により、OMEC-4BGというiSerialNumberのUSBデバイスが/dev/ttyOMEC-4GBというシンボリックリンクに関連付けされます。
「USB-Serialデバイスを沢山接続するので/dev以下にシンボリックリンクが増えすぎるのは目障りだ」というのであれば、`SYMLINK+="ttyUSB/OMEC-4GB"'のようにディレクトリに入れることもできます。`ttyUSB'というディレクトリは自動的に作成されます。
`MODE="0666"'は、生成されるデバイスファイルのパーミッション(アクセス権限)の設定です。この場合は、全てのユーザーにアクセス権を与えています。特に設定しない場合でも使用は可能ですが。root権限でなければアクセスできないかも知れません。
パーミッション666が嫌だというのであれば、`GROUP="users" MODE="0660"'とすることも可能です(むしろ、この方が良いかもしれません)。
このようなセクションを、デバイスの分だけ`/etc/udev/rules.d/51-usbserial.rules'に記載することになります。勿論、`SYMLINK+="ttyOMEC-4GB"'の部分は各デバイスのiSerialNumberに読みかえます。
上の例では、ttyとserialだけで識別していましたが、勿論productやmanufacturerを追加して指定することも可能です。その場合は、以下のようになるでしょう。udevinfo -a -p /class/tty/ttyUSB0
の実行結果から、必要な部分をコピーするだけです。
SUBSYSTEM=="tty", SYSFS{manufacturer}=="FTDI", SYSFS{product}=="USB HS SERIAL CONVERTER", SYSFS{serial}=="OMEC-48G", SYMLINK+="ttyOMEC-4GB" MODE="0666" |
manufactureやproductの代わりにidVendorやidProductも使用可能です。
何かルールファイルを修正した場合はudevstart
を実行しておきます(コマンドが無い場合もあります。udevcontrol reload_rules
を実行しても良いかもしれません)。
# udevstart |
上述の通りに設定すれば、/dev/以下にデバイス固有のデバイスファイル(シンボリックリンク)ができる筈です。このデバイスファイルを操作することにより、特定のシリアルデバイスを操作することが可能になります。
試しに、USB-Serialコンバーターを抜き差ししながらデバイスファイルが出来ているかどうか確認してみましょう。
# ls /dev/ … ttyOMEC-4GB … ttyUSB0 … |
ttyOMEC-4GBはttyUSB0へのシンボリックリンクになっていると思います。
# ls -la /dev/ttyOMEC-4GB lrwxrwxrwx 1 root root 7 12月 14 17:03 /dev/ttyOMEC-4GB -> ttyUSB0 |
USB-Serialコンバーターを取り外すと、
# ls -la /dev/ttyOMEC-4GB ls: /dev/ttyOMEC-4GB: そのようなファイルやディレクトリはありません |
と、なります。 もう一回接続すると、またシンボリックリンクが現れます。
このUSB-Serialコンバーターを取り外し、別のUSB-Serialコンバーターを接続しても、このシンボリックリンクは現れませんが、/dev/ttyUSB0は現れます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
操作方法は、デバイスファイルが違う以外は通常のシリアルデバイスと同じです。
ポイントは、udev.rulesで設定したシンボリックリンクを用いることです。/dev/ttyUSBで始まるデバイスファイルは状況によってどの個体に割り振られるかは分からないのですが、シンボリックリンクは間違いなく目的の個体のデバイスファイルとなっています。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | F L P S U |
---|
Jump to: | F L P S U |
---|
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Katsuhiro DOBASHI on December, 17 2010 using texi2html 1.76.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ < ] | Back | previous section in reading order | 1.2.2 |
[ > ] | Forward | next section in reading order | 1.2.4 |
[ << ] | FastBack | beginning of this chapter or previous chapter | 1 |
[ Up ] | Up | up section | 1.2 |
[ >> ] | FastForward | next chapter | 2 |
[Top] | Top | cover (top) of document | |
[Contents] | Contents | table of contents | |
[Index] | Index | index | |
[ ? ] | About | about (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated by Katsuhiro DOBASHI on December, 17 2010 using texi2html 1.76.