2013年9月26日木曜日

PIC18F14K50でUSBシリアル

日経Linuxの9月号にPIC18F14K50をLinuxで使う、という趣旨の記事が載っています。
要はLinux上のMPLABX環境でPIC18F14K50のCDC(Communication Device Class)のサンプルプログラムをコンパイルして、PICkit3で書き込んで、CDCとして認識させて動かす、というものです。このサンプル自体はずーっと昔にWindows上のMPLABでコンパイルして動かしたことがあるのですが、Linuxではうまく動かず放ってありました。
手持ちに秋月のPIC18F14K50の800円ボードもPICkit3もあるし、ちょっとやってみたいこともあるので試してみました。環境は LinuxMint13 32bit です。
大きな流れとしては、
  1. MPLABXをインストール
  2. MPLAB C18ツールチェーンをインストール
    MPLAB C18ツールチェーンは普通はたどり着けないところにあるので、wget で http://www.microchip.com/mplabc18-linux-installer からツールチェーンをもってきてインストール。これまでうまくいかなかったのはこれ。結局ライブラリは C18 でしか動かない、ってことなのですね。
  3. Microchip Library for Applications をインストール
  4. プロジェクトを作成し、サンプルプログラムを開く。
    IDE v8 Project から CDC Basic Demo - C18 - Low Pin Count USB Development Kit.mcp を開く。 開いたら「Power Target circuit from PICkit3」のチェックボックスをONにして、PICkit3から電源供給できるようにする。
というところです。
で、書き込んだ後、ボードをUSBケーブルでホストPC(Mint13)と接続するのですが、接続後に見えるデバイスは「/dev/ttyACM0」ではなく「/dev/ttyUSB0」と「/dev/ttyUSB1」になってしまいます。ロードされるドライバも cdc_acm ではなく、ftdi_sioがロードされてしまい、正しく動作しません。
この原因は ftdi_sio ドライバにUSBデバイスID「04d8:000a」が記述されていて、そちらがロードされてしまうためのようです。とりあえず回避するには、
$ sudo rmmod ftdi_sio
として、ftdi_sio ドライバを外してやり、その後でUSBケーブルを差し直すと正しく /dev/ttyACM0 として見えて、ちゃんと動作するようになります。恒久的には ftdi_sio ドライバを /etc/modprobe.d の下の blacklist に入れてやればおそらく解決するのでしょうが、当然本物のFTDIチップが動かなくなります。
なんでこんなことになっているかというと、この件のパッチが投げられている
https://patchwork.kernel.org/patch/1464661/によると、FTDIチップをエミュレーションするファームウェアでこのMicrochipの評価ボードのベンダID/デバイスIDをそのまま使っているハードウェアベンダがいるため・・・・ということのようです。(うー、勘弁して・・・・)
ドライバに直接手を入れれば修正できるようなのですが、ちょっと面倒臭いですね・・・。何かいい方法(ベンダID/デバイスIDを指定して blacklist するなど)があればいいのですが・・・。
で、何とかならないかと、試しに /etc/udev/rules.d/10-cdcacm.rules として以下の内容のファイルを作ります。
SUBSYSTEM=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="000a", GROUP="adm", MODE="0666", SYMLINK+="cdc_acm"
udevをリスタートしてルールを読み込ませます。
$ sudo service udev restart
試しに、
$ sudo modprobe ftdi_sio
として、先にrmmod してあった ftdi_sio を読み込ませて、その後で、USBを抜き差ししてみます。
dmesgの最後を見てみると、
[ 5431.756641] udevd[4801]: starting version 175
[ 5479.158712] USB Serial support registered for FTDI USB Serial Device
[ 5479.159765] usbcore: registered new interface driver ftdi_sio
[ 5479.159768] ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
[ 5490.096591] usb 1-1.3: USB disconnect, device number 10
[ 5492.337738] usb 1-1.3: new full-speed USB device number 11 using ehci_hcd
[ 5492.434666] cdc_acm 1-1.3:1.0: This device cannot do calls on its own. It is not a modem.
[ 5492.434688] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
となっていて、とりあえず ttyACM0 として認識しているようです。
しかし再起動してみると・・・・ftdi_sioとして認識してしまう・・・orz
どうやらどちらのドライバが先に認識するか・・・だけみたい。/etc/udev/rules.d/10-cdcacm.rules ではコントロールできなさそうなことはわかりました・・・。
やっぱり ftdi_sioをblacklistして、rules.dでFTDIドライバを読ませるとかすればいいのでしょうかね・・・?
<追伸>
ちなみに、バージョン3.12-rcや3.2.51のカーネルソースでは、上記パッチが適用されてるっぽいです。一方で、
$ uname -a
Linux G530-2-Mint 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:41:14 UTC 2012 i686 i686 i386 GNU/Linux
ん~?カーネルのバージョンを上げれば解決するのだろうか??
Synapticでカーネルパッケージを入れてみました。
$ uname -a
Linux G530-2-Mint 3.2.0-53-generic-pae #81-Ubuntu SMP Thu Aug 22 21:23:47 UTC 2013 i686 i686 i386 GNU/Linux
・・・・治りました。ここまでの苦労は何だったんでしょう(^^;
やっぱり、アップデートはちゃんとやっとかないとダメですね・・・。

0 件のコメント: