これは、シリアルポートを開くための私の関数の外観です(Ubuntu 12.04を使用)。
_int open_port(void)
{
int fd; /* File descriptor for the port */
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
// Could not open the port.
perror("open_port: Unable to open /dev/ttyUSB0 - ");
}
else
fcntl(fd, F_SETFL, 0);
struct termios options;
tcgetattr(fd, &options);
//setting baud rates and stuff
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);
tcsetattr(fd, TCSAFLUSH, &options);
options.c_cflag &= ~PARENB;//next 4 lines setting 8N1
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//options.c_cflag &= ~CNEW_RTSCTS;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input
options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control
return (fd);
}
_
問題は、このプログラムを実行すると、シリアルデバイスが既に接続されている場合、バッファーにコンテンツが含まれていることです。読み取りを開始する前にバッファをクリアする方法が必要です。 tcsetattr(fd, TCSAFLUSH, &options);
を使用すると、ポートを初期化する前にIOバッファをフラッシュすることでこの問題を解決できると思いますが、そのような運はありません。洞察はありますか?
私はそれを理解したと思います。何らかの理由で、フラッシュする前に遅延を追加する必要があります。トリックを実行するために、fd
seemを返す前に追加された次の2行:
sleep(2); //required to make flush work, for some reason
tcflush(fd,TCIOFLUSH);
この問題の原因は、USBシリアルポートの使用にあります。通常のシリアルポートを使用する場合、この問題は発生しません。
ほとんどのUSBシリアルポートドライバーは正しくフラッシュをサポートしていません。おそらく内部シフトレジスタ、FIFOまたはUSBサブシステムにデータがまだあるかどうかを知る方法がないためです。
以前に報告された同様の問題に対するGregの回答 here も参照してください。
あなたのsleep
は問題を解決するかもしれませんが、それは回避策にすぎません。残念ながら、通常のシリアルポートを使用する以外に解決策はありません。
Open()でリセットされるArduino Unoボードでも同様の症状が発生しています。 Arduinoボードがリセットされる前、つまりopen()が呼び出される前に生成されたopen()呼び出しの後にデータを受信していました。
Ioctl()呼び出しによる問題の追跡私は、tcflush()が呼び出されるまでにデータがまだ入力バッファーに到着していないことを知りました。したがって、tcflush()は機能しましたが、フラッシュするデータはありませんでした。 open()呼び出し後の1000 usのスリープで問題が解決したようです。これは、tcflush()が呼び出される前にデータの到着を許可したため、tcflush()が実際に入力バッファーをフラッシュしたためです。
同じ問題が発生している可能性があります。