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

・・・・治りました。ここまでの苦労は何だったんでしょう(^^;
やっぱり、アップデートはちゃんとやっとかないとダメですね・・・。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)