いとうです。何度もすみません。
From: Koh-ichi Ito <[email protected]>
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.