Здраствуйте.
Есть программа работающая на роутере (asus wl-500), которая читает данные от ардуины и пресылает их куда надо.
Вот так открываю порт:
int open_port()
{
int fd;
fd = open(device, O_RDWR | O_NOCTTY); //|O_NONBLOCK);
if(fd == -1)
{
strncpy(er_log_str, "Error - NOT open port.", 31);
error_log();
}
else
{
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 1;
options.c_lflag = ICANON;
options.c_oflag = 0;
options.c_oflag &= ~OPOST;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
}
return fd;
}
...
В цикле ожидаю данных (ардуина посылает их ~два раза в сек.). Чтение блокируется пока нет данных.
...
char bRead[BUFSIZE] = {0,};
int err_count1 = 0;
unsigned int i = 0;
while(!VINTR)
{
int bytes = 0;
memset(bRead, 0, sizeof(bRead));
if((bytes = read(fd, bRead, BUFSIZE))==-1)
{
printf("Error read.\n");
}
printf("bytes: %d\n\n", bytes);
for(i = 0; i<=strlen(bRead); i++)
{
if(bRead[i] == '\r' || bRead[i] == '\n')
{
bRead[i] = 0;
tcflush(fd, TCIFLUSH);
break;
}
}
//////////////////////// Проверка A-Z /////////////////////////////////////
if(bRead[0] == 'A' && bRead[strlen(bRead)-1] == 'Z')
{
err_count1 = 0;
printf("OK A-Z\n");
}
else
{
tcflush(fd, TCIFLUSH);
err_count1++;
if(err_count1 > 10)
{
strncpy(er_log_str, "Not A-Z.", 31);
error_log();
}
printf("Not_A-Z_bRead: %s\n\n", bRead);
continue;
}
host = gethostbyname("192.168.1.1"); // 192.168.1.1
memset((char *) &server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(3495);
server.sin_addr = *((struct in_addr*) host->h_addr);
if(sendto(sockfd, bRead, strlen(bRead), 0, (struct sockaddr *) &server, sizeof(server)) < 0)
{
strncpy(er_log_str, "ERROR sendto.", 31);
error_log();
}
printf("bRead: %s\n\n", bRead);
} // Конец основного цикла (while)
...
Суть работы такова:
Ардуина посылает строку - «A 1 1 1 1 1 1 1 1 1 1 1 0 0 Z».
read() - её ловит.
for(i = 0; i<=strlen(bRead); i++) - отыскивает конец строки.
if(bRead[0] == 'A' && bRead[strlen(bRead)-1] == 'Z') - проверяет первый и последний символ, и если всё хорошо, тогда эти данные отправляются по UDP.
Если проверка «A...Z» неудачная, то возврат к началу цикла (while(!VINTR)).
Вопрос заключается в следующем:
В представленном выше виде, всё работает хорошо, ошибок «A...Z» нет. Однако если убрать строчку «printf(„bytes: %d\n\n“, bytes);», которая идёт после read():
...
while(!VINTR)
{
int bytes = 0;
memset(bRead, 0, sizeof(bRead));
if((bytes = read(fd, bRead, BUFSIZE))==-1)
{
printf("Error read.\n");
}
printf("bytes: %d\n\n", bytes); // эта строчка
...
...
if(err_count1 > 10)
{
strncpy(er_log_str, "Not A-Z.", 31);
error_log();
}
printf("Not_A-Z_bRead: %s\n\n", bRead);
continue;
...
Если вместо злосчастной строки «printf(„bytes: %d\n\n“, bytes);» вставить паузу, хотя бы на одну микросекунду (usleep(1);), то ошибка исчезает. Иными словами, получается что после read() зачем-то нужна крохотная задержка.
Как объяснить такое поведение? Причём это проявляется только на роутере, если запускать прогу на «большом компе», то ошибок нет.