趣味の電子工作などの記録。時にLinuxへ行ったり、ガジェットに浮気したりするので、なかなかまとまらない。
RSS icon
  • PIC18F14K50でUSBシリアル

    投稿日 2013年 9月 26日 コメントはありません

    日経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

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


    コメントをどうぞ(日本語のみ/Only in Japanese)

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