2013-02-13 3 views
0

Эта программа (я считаю) прямое применение select() (на Debian для ARM). XBEEDEVICE указывает на последовательный порт. Последовательный порт существует и подключен к устройству.select() истекает, хотя в буфере есть данные

Проблема есть, select() возвращает 0, хотя есть данные. Я временно прокомментировал последнее «еще», и программа печатает TIMEOUT, а затем строку, которая была возвращена удаленным устройством.

int main(int argc, char **argv) { 
    int fd, c, res, n; 
    struct termios oldtio, newtio; 
    char buf[255] = {0}; 

    fd_set input; 
    struct timeval timeout; 

    // define timeout 
    timeout.tv_sec = 5; 
    timeout.tv_usec = 0; 

    fd = open(XBEEDEVICE, O_RDWR | O_NOCTTY); 
    if(fd < 0){ 
    perror(XBEEDEVICE); 
    return(-1); 
    } 

    tcgetattr(fd, &oldtio); /* save current port settings */ 
    bzero(&newtio, sizeof(newtio)); 
    newtio.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD; 
    newtio.c_iflag = IGNPAR; 
    newtio.c_oflag = 0; 

    /* set input mode (non-canonical, no echo,...) */ 
    newtio.c_lflag = 0; 

    newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ 
    newtio.c_cc[VMIN]  = 2; /* blocking read until 2 chars received */ 

    tcflush(fd, TCIFLUSH); 
    tcsetattr(fd, TCSANOW, &newtio); 

    // Sending +++ within 1 second sets the XBee into command mode 
    printf(" Sending +++\n"); 
    write(fd, "+++", 3); 

    n = select(fd, &input, NULL, NULL, &timeout); 

    if(n < 0) 
    printf("select() failed\n"); 
    else if(n == 0) 
    printf("TIMEOUT\n"); 
    //else{ 
    res = read(fd, buf, 250); 
    buf[res] = 0; 
    printf("Received: %s\n", buf); 
    //} 
    tcsetattr(fd, TCSANOW, &oldtio); 

    return(0); 
} 
+0

Вы должны добавить больше тегов на свои вопросы. У Stackoverflow есть хорошая система, чтобы уведомлять людей об их любимых тегах, поэтому другим будет легче найти ваш вопрос, если вы добавите более релевантные теги ... –

ответ

3

Вы должны инициализировать input содержать fd. Это делается с помощью FD_ZERO и FD_SET макросов:

FD_ZERO(&input); 
FD_SET(fd, &input); 

Это должно быть сделано делать каждый раз, прежде чем select называется.

Первый аргумент select должен быть fd+1. Число проверяемых файловых дескрипторов в диапазоне. Так как максимальное (и только) число дескрипторов в диапазоне составляет fd, а минимум всегда 0, число, о котором идет речь, равно fd+1.

+0

Спасибо, я попробую сегодня. Я пробовал fd + 1 (но не FD_ZERO() или FD_SET()), и это не имело никакого значения. –

+0

Я добавил вызовы FD_ZERO() и FD_SET() и изменил 'fd' на fd + 1 ', и теперь он работает. Большое спасибо! –