2012-06-05 2 views
3

select, FD_ISSET, read 등을 사용하여 ttyUSB 포트에서 읽는 일부 Linux C 코드에 문제가 있습니다. 모뎀에서 FTDI 직렬 직렬 USB 케이블을 입력으로 사용합니다. 문제는 USB 케이블이 뽑혀있을 때 선택 해제를 해제하는 것입니다. 그것을 막을 수있는 방법이 있습니까?왜 USB 케이블이 연결되지 않았습니까?

count = 0; 
while (g_running) { 
    FD_ZERO(&readFdSet); 
    maxfd = 0; 
    numTransPorts = 0; 
    logger(DEBUG, "Begin g_running loop - %d", count); 
    for (i = 0; i < MAX_CONFIG_PORTS; i++) { 
     if (configPorts[i].commType == 1 && configPorts[i].pttyHost != NULL) { 
     FD_SET(configPorts[i].pttyHost->fd, &readFdSet); 
     logger(DEBUG, "FD_SET - fd=%d, index=%d", configPorts[i].pttyHost->fd, i); 
     if (configPorts[i].pttyHost->fd >= maxfd) { 
      maxfd = configPorts[i].pttyHost->fd; 
     } 
     numTransPorts++; 
     } 
    } 
    maxfd++; // add one because select check a range to n-1 file descriptors 
    if (maxfd != 0) { // indicates no ports are available 
     logger(DEBUG, "Calling select() with %d ports and maxfd of %d", numTransPorts, maxfd); 
     logger(INFO, "Waiting for input ..."); 
     select(maxfd, &readFdSet, NULL, NULL, NULL); // blocking until one available 
     if(result == -1){ 
     logger(INFO, "select() error. errno: %d", errno); 
     } else if (result > 0){ 
     for (i = 0; i < MAX_CONFIG_PORTS; i++) { 
      if (FD_ISSET(configPorts[i].pttyHost->fd, &readFdSet)) { // input is available 
       logger(INFO, "Input on port %s", configPorts[i].pttyHost->serialPath); 
       result = serialPortRead(buffer, configPorts[i].pttyHost->fd); 
       if (result <= 0) { 
        // there was an error due to the file descriptor. It 
        // probably indicates that the tty ports are no longer available 
       } 
      } 
     } 
     } else { 
     logger (INFO, "select() returns 0"); 
     } 
    } 
    count++; 
} 

serialPortRead : USB 케이블 연결이 해제되면

int serialPortRead(char *buf, int serialHandle) { 
    //char ch; 
    char *ptr; 
    int res = 0; 
    int bytesRead = 0; 
    int i; 

    logger(TRACE, "TRACE: serialPortRead() with fd = %d", serialHandle); 

    ptr = buf; 

    // try 3 times 
    for (i = 0; i < 3; i++) { 
     while ((res = read(serialHandle, ptr, 1)) > 0) { // read 1 byte at a time 
     if (*ptr == 0x0d) { //there is 0x0d as a terminate byte from ECR 
      break; 
     } 
     ptr += res; 
     } 
     if (res < 0 && errno == EAGAIN) { 
     continue; 
     } else { 
     break; 
     } 
    } 

    *ptr = 0x00; // set 0x00 as a terminate byte 
    // pthread_mutex_unlock(&g_serial_trans_mutex); 
    if (res < 0) { 
     // if res is -1, there is an error 
     bytesRead = -1; 
     logger(DEBUG, "serialPortRead error. errno = %d", errno); 
    } else { 
     bytesRead = (int) (ptr - buf); 
     logger(DEBUG, "serialPortRead %d bytes", bytesRead); 
    } 

    return bytesRead; 
} 

는, 선택() 차단을 해제, 입력을 의미하는 것은 FD_ISSET가 true를 반환 할 수 있습니다. serialPortRead의 read()는 읽은 0 바이트를 반환합니다. 그런 다음 입력을 사용할 수 있음을 다시 차단 해제하는 select()로 돌아갑니다. 따라서 select(), FD_ISSET이 true를 반환하고 fd가 지워지지 않고 read가 0을 반환하는 등의 무한 루프가 발생합니다. 이 문제를 어떻게 해결할 수 있습니까? 예상 할 수있는 동작은 실제로 읽을 내용이 없을 때 select가 잘못 차단되지 않는다는 것입니다.

참고 : 선택을 해제한다 때 읽을 수있는 정보가 있기 때문에

+1

선택 반환은 '입력 가능'이라는 의미입니까? afaik 그것은 또한 '오류가 있습니다'를 의미 할 수 있습니다. 정확하게 여기에있는 경우입니다. – stijn

+0

read가 0을 반환 할 때, 더 읽을 것이 아무것도 없기 때문에, 당신은 당신이 선택하고있는 세트에서 fd를 가져와야합니다. 오류가 발생하면 오류가 사용자에게 전달 될 수 있습니다. 오류에 대한 정보를 얻은 후에는 fd를 닫고 선택 및 읽기를 계속하기보다는 선택을 중지해야합니다. –

+0

내가 바라는 행동은 그것이 작동하는 방식이 아니라는 것입니다. 앱이 시작되면 USB 장치가 꽂혀 있고 입력을 위해 열립니다. 우연히 플러그를 뽑지 않으면 구성이 변경되어서는 안됩니다. 나는 단지 아무 것도하지 않기를 바랄뿐입니다. 그런 다음 케이블을 다시 꽂으면 방해받지 않고 입력을받을 수 있습니다. – Jim

답변

5

select()이 반환 양수 반환 -이 경우를, 파일 기술자가 "파일의 끝"에 도달한다는 사실. 이것은 으로 표시되며 0을 반환합니다.

read()0 인 경우 해당 파일 설명자를 닫아야합니다.

+0

내가 할 일은 fd를 닫아야한다는 것입니다. 그러나, 나는 처음부터 차단 해제에서 선택을 방지하는 몇 가지 방법이 있었으면 좋았을 텐데. 그런 다음 케이블을 다시 연결하면 앱이 입력을받을 수있는 상태가됩니다. 예를 들어, RS232 케이블을 뽑으면 이벤트를 트리거하지 않고 다시 꽂을 수 있습니다. – Jim

+3

@ user1100151 : USB tty가 작동하는 방식이 아닙니다. USB tty를 분리하고 다시 연결할 때, 사라지고 다시 나타나는 전체 직렬 포트 장치입니다. 커널은 동일한 USB 장치가 다시 나타나는지 또는 다른 USB 장치인지를 알 수 없으므로 각 플러그 이벤트에 새 장치 노드를 만듭니다. 유선 RS232 직렬 포트를 사용하면 직렬 장치 자체가 절대로 없어지지 않습니다. – caf

관련 문제