« XILINXの古いXSDK(2018.3)をインストールする | トップページ | DigikeyでRaspberry Pi5が買えるようになっています »

2023.12.02

ZYNQのLinuxでUSBシリアル変換ケーブルを利用する方法

RS232Cで制御する機器(1軸ステージ)をZYNQのLinuxからコントロールしたいので、ZYNQ LinuxからUSBシリアル変換器を扱う方法を調べました。

やりたいことは、Cosmo-Z MiniにUSBシリアルケーブルをつないで1軸ステージを動かすことです。

Cszminiusbserial

まず、LinuxはUSBに新たなハードウェアがつながるとlsusbコマンドで何がつながっているかが表示されます。

root@cszmini:~# lsusb
Bus 001 Device 004: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

しかし、ここで表示されたからといって使えるわけではありません。そのハードウェアが使えるかどうかはカーネルのコンパイル時にあらかじめ指定してあるかどうかで決まります。カーネルのコンパイル時に指定していなければ絶対に使えません。

なお、USBシリアル変換ケーブルにはCP210xやPL2303系、FTDI系などいろいろありますが現在のLinuxではすべてサポートされています。しかし、デフォルトでは有効になっていません。

これらを使うためカーネルのコンパイルで有効にするやり方ですが、まず、

cat /proc/config.gz | gunzip -c > .config

とやって、現在のコンフィグ情報をファイルに落とします。

これをLinuxをコンパイルするPCのLinux構築フォルダにコピーして、

make ARCH=arm menuconfig

でメニューコンフィグを出して、Device Driverの、

Kern1

USBの

Kern2

USB Serial Converter Supportを出します。

まず、ここが[ ]なので、[*]にします。

Kern3

中に入ったら上から3つくらいを有効[*]にします。(する必要があるかどうかはわからないけど一応)

CP2104やFTDIなどのメジャーどころと、

Kern4

そしてPL2303も有効にします。

Kern5

こうして

make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage

でコンパイルして新しくできたuImageでLinuxを起動すればサクッと認識されます。

認識されるとdmesgのメッセージにも残りますが、/dev/ttyUSB0としてドライバが作られます。

Pl2303

このドライバに対して

echo "Hello" > /dev/ttyUSB0

とすれば文字列が出力されます。

逆に、

cat /dev/ttyUSB0 

で受信文字列が表示されるのですが止まらなくなってしまうので、もう一工夫が必要なようです。

echo "Hello" > /dev/ttyUSB0

で出力された信号をオシロで見てみると、デフォルトでは9600bpsになっていました。

9600bps

速度を変更するにはsttyコマンドを使って、

stty -F /dev/ttyUSB0 speed 115200

とすればよいようです。

変更すると115200bpsになりました。

115200bps

C言語で扱うサンプルプログラムを書いてみました。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
int main()
{
int fd = open("/dev/ttyUSB0",O_RDWR);
if(fd < 0) return -1;
struct termios term;
cgetattr(fd, &term); // 現在の設定を得る
cfsetspeed(&term, B115200); // 115200baudに設定
cfmakeraw(&term); // RAWモード
tcsetattr( fd, TCSANOW, &term ); // 設定は即時反映させること
ioctl(fd, TCSETS, &term); // 設定を反映
write(fd, "Hello", 5);
usleep(100000); // 送受信待ち
char buf[256];
int len = read(fd, buf, sizeof(buf)); // 受信
buf[len] = '\0';
printf("Recv: '%s' %dBytes\n",buf,len);
close(fd);
}

ポイントとしては、

① ボーレートを設定するB115200というのはマクロ定義された値

② RAWモードにしないと、受信したときに送信を延々と繰り返してしまうので、必須

③ 受信のreadはブロックしない。長めの長さを与えておいてもOK。(受信文字列の組み立ては自分でやるということ)

です。

 

|

« XILINXの古いXSDK(2018.3)をインストールする | トップページ | DigikeyでRaspberry Pi5が買えるようになっています »

コメント

コメントを書く



(ウェブ上には掲載しません)




« XILINXの古いXSDK(2018.3)をインストールする | トップページ | DigikeyでRaspberry Pi5が買えるようになっています »