// testserial.c // // Copyright 2009 Yuji Noizumi // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA. #include #include #include #include #include #include #include #include #define _POSIX_SOURCE 1 /* POSIX 準拠のソース */ #define BUFMAX 256 /* Serial port difine */ #define BAUDRATE B9600 char serial_r_buf[BUFMAX]; int fd; struct termios oldtio; /* current serial port settings (現在のシリアルポートの設定を待避)*/ /**************************************************************************** * 関数名:open_serial_port() * 説明:シリアルデバイスをOpenする。 * 【引数】 * char *modem_dev Openするシリアルデバイス文字列 * 【戻り値】 * int 0固定 *****************************************************************************/ int print_termios(struct termios *tioold,struct termios *tionew){ printf("c_cflag : %X\t%X\n",tioold->c_cflag,tionew->c_cflag); printf("c_iflag : %X\t%X\n",tioold->c_iflag,tionew->c_iflag); printf("c_oflag : %X\t%X\n",tioold->c_oflag,tionew->c_oflag); printf("c_lflag : %X\t%X\n",tioold->c_lflag,tionew->c_lflag); printf("c_cc[VINTR] : %X\t%X\n",tioold->c_cc[VQUIT],tionew->c_cc[VQUIT]); printf("c_cc[VERASE] : %X\t%X\n",tioold->c_cc[VERASE],tionew->c_cc[VERASE]); printf("c_cc[VKILL] : %X\t%X\n",tioold->c_cc[VKILL],tionew->c_cc[VKILL]); printf("c_cc[VEOF] : %X\t%X\n",tioold->c_cc[VEOF],tionew->c_cc[VEOF]); printf("c_cc[VTIME] : %X\t%X\n",tioold->c_cc[VTIME],tionew->c_cc[VTIME]); printf("c_cc[VMIN] : %X\t%X\n",tioold->c_cc[VMIN],tionew->c_cc[VMIN]); printf("c_cc[VSWTC] : %X\t%X\n",tioold->c_cc[VSWTC],tionew->c_cc[VSWTC]); printf("c_cc[VSTART] : %X\t%X\n",tioold->c_cc[VSTART],tionew->c_cc[VSTART]); printf("c_cc[VSTOP] : %X\t%X\n",tioold->c_cc[VSTOP],tionew->c_cc[VSTOP]); printf("c_cc[VSUSP] : %X\t%X\n",tioold->c_cc[VSUSP],tionew->c_cc[VSUSP]); printf("c_cc[VEOL] : %X\t%X\n",tioold->c_cc[VEOL],tionew->c_cc[VEOL]); printf("c_cc[VREPRINT] : %X\t%X\n",tioold->c_cc[VREPRINT],tionew->c_cc[VREPRINT]); printf("c_cc[VDISCARD] : %X\t%X\n",tioold->c_cc[VDISCARD],tionew->c_cc[VDISCARD]); printf("c_cc[VWERASE] : %X\t%X\n",tioold->c_cc[VWERASE],tionew->c_cc[VWERASE]); printf("c_cc[VLNEXT] : %X\t%X\n",tioold->c_cc[VLNEXT],tionew->c_cc[VLNEXT]); printf("c_cc[VEOL2] : %X\t%X\n",tioold->c_cc[VEOL2],tionew->c_cc[VEOL2]); return 0; } /*----- Open serial port method -----*/ int open_serial_port(char *modem_dev){ struct termios newtio; /* Open modem device for reading and writing and not as controlling tty */ /* 読み書きの為にモデムデバイスをオープンする。ノイズによってCTRL-Cが たまたま発生しても接続が切れないようにtty制御はしない */ fd=open(modem_dev,O_RDWR | O_NOCTTY); if(fd < 0){ perror(modem_dev); exit(-1); } tcgetattr(fd,&oldtio); bzero(&newtio, sizeof(newtio)); /* 新しいポートの設定の構造体をクリアする */ /* Settings for new port BAUDRATE : Set bps rate. You could also use cfsetispeed and cfsetospeed. ボーレートの設定。cfsetispeed,cfsetospeedも使用できる CRTSCTS : Output hardware flow control ( only used if the cable has all necessary lines. See sect. 7 of Serial-HOWTO ) 出力のハードウェアフロー制御(必要な結線が全てされているケースのみ) CS8 : 8n1 ( 8bit,no parity,1 stopbit) CLOCAL : local connection,no modem control CREAD : enable receiving characters 受信文字を有効にする */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD ; /* IGNPAR : ignore bytes with parity errors */ /* (パリティエラーのデータは無視する )*/ /* ICRNL : */ /* (CRをNLに対応させる。これを行わないと他のコンピュータでCRを入力しても 入力が終わりにならない)*/ newtio.c_iflag = IGNPAR; // newtio.c_iflag = 0; newtio.c_oflag = 0; /* Raw output (Rawモードでの出力)*/ newtio.c_lflag = 0; /* Set input mode (non-canonical,no echo,....) */ /* ICANN :カノニカル入力を有効にする 全てのエコーを無効にし、プログラムに対し シグナルは送らせない */ newtio.c_cc[VINTR] = 0; /* Ctrl-c */ newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */ newtio.c_cc[VERASE] = 0; /* del */ newtio.c_cc[VKILL] = 0; /* @ */ newtio.c_cc[VEOF] = 4; /* Ctrl-d */ newtio.c_cc[VTIME] = 0; /* キャラクタ間タイマを使わない */ newtio.c_cc[VMIN] = 1; /* 1文字来るまで,読み込みをブロックする */ newtio.c_cc[VSWTC] = 0; /* '\0' */ newtio.c_cc[VSTART] = 0; /* Ctrl-q */ newtio.c_cc[VSTOP] = 0; /* Ctrl-s */ newtio.c_cc[VSUSP] = 0; /* Ctrl-z */ newtio.c_cc[VEOL] = 0; /* '\0' */ newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */ newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */ newtio.c_cc[VWERASE] = 0; /* Ctrl-w */ newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */ newtio.c_cc[VEOL2] = 0; /* '\0' */ cfsetispeed(&newtio, BAUDRATE); cfsetospeed(&newtio, BAUDRATE); /* Now clean the modem line and activate the settings for the port */ /* モデムラインをクリアする */ tcflush(fd,TCIFLUSH); /* 新しい設定を適用する */ tcsetattr(fd,TCSANOW,&newtio); print_termios(&oldtio,&newtio); // DEBUG return 0; } /**************************************************************************** * 関数名:close_serial_port() * 説明:シリアルデバイスをCloseする。 * 【グローバル変数】 * int fd ファイルデスクリプタ * 【引数】 * なし * 【戻り値】 * なし *****************************************************************************/ /*----- Close serial port method -----*/ void close_serial_port(void){ /* Restore the old port settings */ tcsetattr(fd,TCSANOW,&oldtio); close(fd); } /*----- Output a character to current serial port -----*/ int put_serial_char(unsigned char c){ if(write(fd,&c,1) != 1) return -1; return 0; } /*----- Output a string to current serial port -----*/ int put_serial_string(char *s){ if(write(fd,s,strlen(s)) != strlen(s)) return -1; return 0; } /*----- Get a character from current serial port -----*/ int get_serial_char(void){ unsigned char c; int res; res = read(fd,(char *)&c,1); printf("res=%d\n",res); return c; } /*----- Get a string from current serial port -----*/ char *get_serial_string(char *buf,int bufsize){ unsigned char c=0; int res,i=0; while((c!=0x0a)&&(bufsize>i)){ res = read(fd,(char *)&c,1); if( c>=0x0a ){ buf[i++]=c; } } buf[i++]=0; return buf; } /**************************************************************************** * 関数名:send_rbio() * 説明:RBIOへコマンドを送信する。 * 【引数】 * char *cmd "PCR01" 等、RBIOのマイコンに送信する文字列 * 【戻り値】 * char *status(RBIO応答文字列) *****************************************************************************/ char *send_rbio(char *cmd){ char *ret; char buf[BUFMAX]; printf("debug:send_rbio:%s ",cmd); // DEBUG open_serial_port("/dev/ttyUSB0"); strcpy(buf,cmd); strcat(buf,"\n"); if(put_serial_string(buf) != 0){ printf("put_serial_string() error : %s\n",buf); } // \r\nのみの行を空読み ret = get_serial_string(serial_r_buf,BUFMAX); // 真の応答文字列を返す ret = get_serial_string(serial_r_buf,BUFMAX); sscanf(ret,"%s\r\n",buf); strcpy(ret,buf); close_serial_port(); printf("%s\n",ret); // DEBUG return( ret ); } /**************************************************************************** **************************************************************************** * Main * **************************************************************************** *****************************************************************************/ int main(int argc, char *argv[]) { char buf[BUFMAX]; int ret; char rch; open_serial_port("/dev/ttyUSB0"); ret = put_serial_string("pcr01\n"); #if 0 printf("put_serial_string=%d\n",ret); get_serial_string(buf,sizeof(buf)); printf("buf=%s",buf); #else while(1){ rch = get_serial_char(); printf("%02X:%c\n",rch,rch); usleep(50000); /* 0.05sec */ } #endif close_serial_port(); return 0; }