×

1号の足跡(3) Lazuriteの自動テスタをラズパイで作る(その2)

2016-07-02

前回FTDI社FT232をD2XXモードで動かしました。
今回はD2XXモードに切り替えた後、再びUSBシリアルで通信する方法を調べて行きたいと思います。

前回、D2XXモードを使用するためにLinuxカーネルドライバを無効にしました。


sudo rmmod ftdi_sio
sudo rmmod usbserial

1.無効にしたドライバの保存場所を探す

無効にするときにrmmodを使用したのですが、これはftdi_sioとusbserialのカーネルドライバと呼ばれるものを無効にしたという意味です。D2XXを使用するだけであればこの状態でも良いのですが、LazuriteのテストをするためにはD2XXを使用した後にシリアルを再び使用しなくては行けないため、無効にしたドライバを再び有効にする必要があります。

カーネルドライバを有効にするためにはinsmodを使用すれば良いので、まずは無効にしたドライバを探したいと思います。カーネルドライバのファイルは「ドライバ名.ko」なので、「ftdi_sio.ko」と「usbserial.ko」の場所を探してみたいと思います。

pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo find / | grep ftdi_sio.ko
/lib/modules/4.1.19+/kernel/drivers/usb/serial/ftdi_sio.ko
/lib/modules/4.1.19-v7+/kernel/drivers/usb/serial/ftdi_sio.ko
/lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/ftdi_sio.ko

pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo find / | grep usbserial.ko
/lib/modules/4.1.19+/kernel/drivers/usb/serial/usbserial.ko
/lib/modules/4.1.19-v7+/kernel/drivers/usb/serial/usbserial.ko
/lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/usbserial.ko

とりあえず、3つ発見!!一番下のこれらが実際に使用されているドライバです。
/lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/ftdi_sio.ko
/lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/usbserial.ko

2.USBシリアルを使用するプログラムを作成する

テストプログラム本体は個人的に好きなrubyを使用したいと思います。
そこで、Raspberry PiのRuby上でシリアル用のカーネルドライバを有効にしてシリアルを使用する実験してみたいと思います。簡単に動作確認をするため、Lazuriteにはサンプルプログラムのhelloworld.cを書き込んで置きました。

さて、Rubyからシリアルポートを使用するためにはserialportというライブラリを使用すれば良さそうなのですが、「gem install usbserial」のコマンドを打つだけではインストールが上手く行きませんでした。”ruby-dev”というパッケージを事前にインストールしておく必要があります。
↓↓↓↓↓↓失敗した例↓↓↓↓↓↓

pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo gem install serialport
Fetching: serialport-1.3.1.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing serialport:
	ERROR: Failed to build gem native extension.

    /usr/bin/ruby2.1 extconf.rb
mkmf.rb can't find header files for ruby at /usr/lib/ruby/include/ruby.h

extconf failed, exit code 1

Gem files will remain installed in /var/lib/gems/2.1.0/gems/serialport-1.3.1 for inspection.
Results logged to /var/lib/gems/2.1.0/extensions/arm-linux/2.1.0/serialport-1.3.1/gem_make.out

/usr/lib/ruby/include/ruby.hが無いというエラーが発生しています。
ruby.hはrubyの開発用コードに入っていますので、ruby-devをインストールしてからserialportをインストールすればうまくいくはず。

↓↓↓↓↓↓成功した例↓↓↓↓↓↓

pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo apt-get install ruby-dev
... 省略 ...
pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo gem install serialport
 Building native extensions. This could take a while...
 Successfully installed serialport-1.3.1 Parsing documentation for serialport-1.3.1 Installing ri documentation for serialport-1.3.1 Done installing documentation for serialport after 2 seconds 1 gem installed

3.まとめて動作確認

rubyでこんなプログラムを書いてみました。

#! /usr/bin/ruby

require 'serialport'

#
# Halt process when CTRL+C is pushed.
finish_flag=0
Signal.trap(:INT){
        finish_flag=1
}
cmd = "sudo insmod /lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/usbserial.ko"
result = system(cmd)
p cmd
p result

cmd = "sudo insmod /lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/ftdi_sio.ko"
result = system(cmd)
p cmd
p result

# USBポートと通信速度の設定
@port = "/dev/ttyUSB0"
@baud = 115200
sp = SerialPort.new(@port, @baud)

@thread_end = false

Thread.new{
        while finish_flag==0 do
                line = sp.readline
                puts line
        end
        @thread_end = true
}

while @thread_end == false do
        line = gets
        sp.write line
end
sp.close

さて、ここから一回手動でドライバを外し、insmodしてからシリアル通信が復活できるか確認をしてみたいと思います。
lsmodでは、ドライバが外れているのを確認しています。

pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo rmmod ftdi_sio
pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ sudo rmmod usbserial
pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ lsmod
Module                  Size  Used by
brcmfmac              186478  0
brcmutil                5661  1 brcmfmac
joydev                  9024  0
evdev                  11396  8
cfg80211              427817  1 brcmfmac
rfkill                 16018  2 cfg80211
snd_bcm2835            25029  3
snd_pcm                75826  1 snd_bcm2835
snd_timer              19160  1 snd_pcm
snd                    51844  9 snd_bcm2835,snd_timer,snd_pcm
i2c_bcm2708             4770  0
spi_bcm2835             7286  0
bcm2835_gpiomem         3040  0
bcm2835_wdt             3225  0
uio_pdrv_genirq         3164  0
uio                     8000  1 uio_pdrv_genirq
i2c_dev                 5859  0
fuse                   83461  3
ipv6                  347473  30
pi@raspberrypi ~/develop/miniTester/ftdi_test/src $ ./test.rb
"sudo insmod /lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/usbserial.ko"
true
"sudo insmod /lib/modules/4.4.8-v7+/kernel/drivers/usb/serial/ftdi_sio.ko"
true

hello world
hello world
hello world
hello world
^Chello world      <---- Ctrl+Cを押して終了

ということで、無事に動作してくれました。今日はここまで。