Из открытой страницы (2):
O_NONBLOCK or O_NDELAY
When possible, the file is opened in nonblocking mode.
Neither the open() nor any subsequent operations on the file
descriptor which is returned will cause the calling process to
wait.
Для последовательного соединения конечным результатом будет то, что если вы попросите прочитать некоторое количество байтов из последовательного порта, и не будет символов, ожидающих, затем read вернется с -1, и 'errno', вероятно, будет EAGAIN или EWOULDBLOCK.
Так что ваш usleep (8000), вероятно, был попыткой подождать достаточно долго, чтобы устройство ответило, но устройство может не иметьданные для вас;особенно если он находится в середине операции АЦП, это может занять более 8 мс.
Вы можете сделать несколько вещей:
Вы можете (в псевдокоде):
int retries=10;
while(retries--) {
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
if(read_length > 0)
break;
usleep(1000);
}
К сожалению, одним из побочных эффектов этого является то, что, если датчик температуры отправляет вам длинную строку и ваша программа читает (), пока датчик температуры все еще пишет, вы получите частичную строку.Поэтому, если вы знаете длину строки, которую вы ожидаете получить, вы можете использовать ioctl (), чтобы узнать, сколько символов ожидает:
ioctl(fd, FIONREAD, &bytes_avail);
Таким образом, псевдокод будет выглядеть примерно так:
int retries=10;
int bytes_avail=0;
while(retries--) {
if (ioctl(fd, FIONREAD, &bytes_avail) < 0) {
fprintf(stderr, "ioctl failed\n");
return; // Do something here
}
if (bytes_avail >= sizeof(rd_buffer)) {
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
if(read_length > 0)
break;
}
usleep(1000);
}
Если датчик температуры отправляет строку ascii, оканчивающуюся переводом строки или возвратом каретки, код будет выглядеть иначе.