• 検索結果がありません。

第 7 章 シリアル通信 91

7.4 チュートリアル

7.4.2 受信

Step3 プログラムの解説

まず、オープンシステムコールでシリアルポートをオープンします。

第一引数に「/dev/ttyG0」という値を指定しています。この値は、ITC-N4007のUART CN1に割当てられているデバイス ノードです。※1

この値を指定し、実行したオープンシステムコールの戻り値を用いてITC-N4007のUART CN1の制御を行います。

次にtcflush関数を使用して受信バッファ、送信バッファをクリアします。

次に通信パラメータの設定を行います。tcsetattr関数を用いることで設定を行うことができます。

今回作成したプログラムでは以下の設定を行っております。

・ボーレート :38400bps

・データ長 :8bit

・ストップビット :1bit

・パリティチェック:なし

・フロー制御 :ハードウェアフロー制御 ※2

・カノニカルモード:有効 ※3

次にwrite関数を用いてデータの送信を行います。

第一引数にはオープンシステムコール関数で取得したファイルディスクリプタ、第二引数には送信するデータを格納し た配列、第三引数には送信するデータサイズを指定します。

最後にオープンしたシリアルポートのクローズを行います。

オープンしたシリアルポートは終了時には必ずクローズを行ってください。

※1 シリアルポートのデバイスノード「/dev/ttyGxx」はデバイスの認識した順番に番号が割り振られていきます。そのため、

デバイスごとの一意な名前ではありません。

デバイス名を確認するにはコンソール上で「cat /proc/tty/driver/cp4161」と入力します。

入力後、デバイスノード、製品型式が表示されます。

#cat /proc/tty/driver/cp4161

ttyG0: PCI/LPC-466120(P)(bid=0h) CH1 [9600bps] tx:0 rx:0 ttyG1: PCI/LPC-466120(P)(bid=0h) CH2 [9600bps] tx:0 rx:0

※ITC-N4007のUART CN1, CN2はそれぞれPCI-466120 CH1, CH2として表示されます。

前面下側には16550互換のUARTが2ポート搭載されています。

デバイスノードはそれぞれ、/dev/ttyS0、/dev/ttyS1となります。

※2 フロー制御については「7.1.8 フロー制御」のハードウェアフロー制御を参照してください。

ケーブルの結線については「7.3 環境図」を参照してください。

※3 カノニカルモードが有効な場合、送受信が行単位での動作となります。

送信の場合、行区切り文字をwrite関数に渡すまでデータの送信を行いません。

受信の場合、行区切り文字を受け取るまでread関数の処理から抜けません。

7.4.2 受信

Step1 プログラム作成

エディタを起動し、下記に示すプログラムを入力して、ファイル名を「Receive.c」として保存してください。

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <termios.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <errno.h>

#include <linux/serial.h>

#include <asm/ioctls.h>

#define BAUDRATE B38400 char Recv_Buf[255];

int main(void) {

int fd;

int Ret;

struct termios Newtio;

// ポートのオープン

fd = open("/dev/ttyG1", O_RDWR | O_NOCTTY );

if ( fd < 0 ) {

printf( "Open fd Error ! Exit !¥n " );

return -1;

}

bzero( &Newtio, sizeof( Newtio ) );

Newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL| CREAD;

Newtio.c_iflag = IGNPAR | ICRNL;

Newtio.c_oflag = 0;

Newtio.c_lflag = ICANON;

// バッファのクリア

Ret = tcflush( fd, TCIOFLUSH );

if (Ret != 0 ){

printf( " tcsetattr Error ¥n" );

close( fd );

exit( -1 );

}

// 通信パラメータの設定

Ret = tcsetattr( fd, TCSANOW , &Newtio );

close( fd );

exit( -1 );

}

// 受信データを取得

if ( ( Ret = read( fd, Recv_Buf, 255 ) ) == -1 ) { printf( "Read Return Error ¥n" );

close( fd );

return -1;

}

// 受信データの表示 Recv_Buf[Ret] = 0;

printf( "Receive Characters¥n%s ",Recv_Buf );

// ポートのクローズ close( fd );

}

次にMakefileを作成します。エディタを起動し、下記に示すコードを記述します。

CC = gcc

TARGET = Receive all: $(TARGET) clean:

rm -f $(TARGET) *~

コードの記述が終わったら保存してください。

保存するファイル名は「Makefile」としてください。

Step2 コンパイル/実行

ソースコード・Makefileを保存したディレクトリに移動し、コマンドラインから下記コマンドを実行します。

下記コマンドを実行することでコンパイルを行う事が出来ます。

make

コンパイルが成功すると、オブジェクトファイル「Receive.o」と実行ファイル「Receive」が作られます。

※ErrorやWarningが表示された場合はコードの記述に誤りがありますので内容を見直してください。

プログラムを実行するには、以下のコマンドを実行します。

./Receive

実行すると何も表示されず処理が停止します。

この状態で「送信」で作成したプログラムを実行してください。

「送信」のプログラム実行後、正常に処理が終了すると下記が表示されます。

Receive Characters 0123456789ABCDEFG

今回作成したプログラムはシリアルデータの受信を行うプログラムです。

データの受信を行うには、read関数を使用します。

ITC-N4007のUART CN2でデータを受信し、受信したデータを表示します。

Step3 プログラムの解説

まず、オープンシステムコールでシリアルポートをオープンします。

第一引数に「/dev/ttyG1」という値を指定しています。この値は、ITC-N4007のUART CN2に割当てられているデバイス ノードです。※1

この値を指定し、実行したオープンシステムコールの戻り値を用いてITC-N4007のUART CN2の制御を行います。

次にtcflush関数を使用して受信バッファ、送信バッファをクリアします。

次に通信パラメータの設定を行います。tcsetattr関数を用いることで設定を行うことができます。

今回作成したプログラムでは以下の設定を行っております。

・ボーレート :38400bps

・データ長 :8bit

・ストップビット :1bit

・パリティチェック:なし

・フロー制御 :ハードウェアフロー制御 ※2

・カノニカルモード:有効 ※3

次にread関数を用いてデータの送信を行います。

第一引数にはオープンシステムコール関数で取得したファイルディスクリプタ、第二引数には受信したデータを格納す る配列のポインタ、第三引数には受信する最大データサイズを指定します。

関数の戻り値には実際に受信できたデータサイズが返されます。

最後にオープンしたシリアルポートのクローズを行います。

オープンしたシリアルポートは終了時には必ずクローズを行ってください。

※1 シリアルポートのデバイスノード「/dev/ttyGxx」はデバイスの認識した順番に番号が割り振られていきます。そのた め、デバイスごとの一意な名前ではありません。

デバイス名を確認するにはコンソール上で「cat /proc/tty/driver/cp4161」と入力します。

入力後、デバイスノード、製品型式が表示されます。

#cat /proc/tty/driver/cp4161

ttyG0: PCI/LPC-466120(P)(bid=0h) CH1 [9600bps] tx:0 rx:0 ttyG1: PCI/LPC-466120(P)(bid=0h) CH2 [9600bps] tx:0 rx:0

※ITC-N4007のUART CN1, CN2はそれぞれPCI-466120 CH1, CH2として表示されます。

前面下側には16550互換のUARTが2ポート搭載されています。

デバイスノードはそれぞれ、/dev/ttyS0、/dev/ttyS1となります。

※2 フロー制御については「7.1.8 フロー制御」のハードウェアフロー制御を参照してください。

信号線(RS、CS)が配線されていない場合正常に送受信を行うことができません。

ケーブルの結線については「7.3 環境図」を参照してください。

※3 カノニカルモードが有効な場合、送受信が行単位での動作となります。

送信の場合、行区切り文字をwrite関数に渡すまでデータの送信を行いません。

受信の場合、行区切り文字を受け取るまでread関数の処理から抜けません。

ドキュメント内 Linuxデバイスドライバチュートリアル (ページ 102-110)