いとうです。何度もすみません。 From: Koh-ichi Ito <k...@kkdlabs.jp> Subject: [FreeBSD-users-jp 94048] Re: umodem で PICC18F2550 にアクセスすると不安定 Date: Mon, 12 Nov 2012 19:38:44 +0900
>> デバイスドライバを書く側から見たら、いつデータが来るか >> わからないときは「100回以上回しても平気」なほうの構造 >> にするか、センサ側がデータ送出指令を待つようにすべきだ >> と思いますが、運がよければ、最初のプログラム構造でも、 >> sleep() を close() の後に移動すると(完全ではないにして >> も)改善されるかもしれないですね。 >> >> 平林 浩一 > > 実は本番の(というほど大げさな話じゃないんですけど :-)プログラムは Perl > じゃなくって C で書いているんですが、ともかく close()の後ろに sleep()を > 入れると改善されることはわかりましたので、がんばってみます。 C のコードでは、close()の後ろに sleep()を入れてみても現象は変わらず、 read()の前の select()がタイムアウトし、そのまま再実行すると、select()が タイムアウトすらせず返ってこなくなります。^C を打鍵するとプロンプトは返っ てきます。 長くて恐縮ですが試したコードを載せます。PAUSE の値は1でダメだったので5 にしてみましたが、やはりダメでした。 #include <err.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <termios.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/select.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/uio.h> #define PAUSE 5 main() { int i, fd; size_t rlen, tlen; ssize_t n; char *tmesg, rmesg[16]; fd_set fds; struct termios tios; struct timeval timeout; for (i = 0; ; i++) { printf("i = %d\n", i); if ( (fd = open("/dev/ttyU0", O_RDWR | O_NONBLOCK) ) < 0) { err(1, "open()"); } if (ioctl(fd, TIOCEXCL) < 0) { err(1, "ioctl(TIOCEXCL)"); } if (tcflush(fd, TCOFLUSH) < 0) { err(1, "tcflush(TCOFLUSH)"); } if (tcflush(fd, TCIFLUSH) < 0) { err(1, "tcflush(TCIFLUSH)"); } if (tcgetattr(fd, &tios) < 0) { err(1, "tcgetattr()"); } tios.c_cflag |= (CREAD | CLOCAL); tios.c_iflag |= IXANY; tios.c_iflag &= ~(ISTRIP | ICRNL | INLCR | IXON | IXOFF | IMAXBEL); tios.c_lflag |= ICANON; tios.c_lflag &= ~(ECHO | ECHONL); tios.c_oflag &= ~OPOST; if (tcsetattr(fd, TCSADRAIN, &tios) < 0) { err(1, "tcsetattr()"); } FD_ZERO(&fds); FD_SET(fd, &fds); timeout.tv_sec = 1; timeout.tv_usec = 0; tmesg = "BARH\r\n"; tlen = strlen(tmesg); if ( (n = select(fd + 1, NULL, &fds, NULL, &timeout) ) < 0) { err(1, "select() for write()"); } else if (n == 0) { fprintf(stderr, "select() for write() timeout.\n"); close(fd); sleep(PAUSE); exit(1); } if (write(fd, tmesg, tlen) < 0) { err(1, "write()"); } FD_ZERO(&fds); FD_SET(fd, &fds); if ( (n = select(fd + 1, &fds, NULL, NULL, &timeout) ) < 0) { err(1, "select() for read()"); } else if (n == 0) { fprintf(stderr, "select() for read() timeout.\n"); close(fd); sleep(PAUSE); exit(1); } bzero(rmesg, 16); if ( (n = read(fd, rmesg, 15) ) < 0) { err(1, "read()"); close(fd); sleep(PAUSE); exit(1); } printf("rmesg: %s\n", rmesg); close(fd); sleep(PAUSE); } } ----- kkdlabs.jp, featuring Koh-ichi Ito as just another DNS freak in town.