2014-10-22 10 views
1

시리얼 장치를 MacBook Air에 연결하는 시리얼 to USB 변환기 (FTDI, 드라이버는 http://www.ftdichip.com/Drivers/VCP.htm에서 설치)가 있습니다. MacBook에 /dev/cu.usbserial-A4017CQY/dev/tty.usbserial-A4017CQY으로 표시됩니다. 내가 설명한 모든 행동은 내가 사용하는 두 가지 방법에 관계없이 동일합니다.O_NONBLOCK 플래그없이 OS X의 시리얼 포트를 열어도

편집 : /dev/cu.*을 사용하여 문제를 해결했습니다. 처음이 질문을 올렸을 때 왜 작동하지 않는 것 같아요. 올바른 방향으로 나를 가리키는 duskwuff 덕분에 그는 은 흐름 제어를 기다리는 반면 /dev/cu.*은 TTY 이름을 거꾸로 가지고 있습니다.

첫 번째 문제는 O_NONBLOCK 플래그를 사용하지 않으면 시스템 호출이 open()으로 영원히 차단된다는 것입니다. 플래그를 사용하면 좋은 파일 설명자를 얻을 수 있지만 write()은 실제로 쓰지 않는 것 같습니다 (바이트를 쓰는 것이 좋습니다). read()은 "자원을 일시적으로 사용할 수 없습니다"오류로 실패합니다.

stty -af /dev/cu.usbserial-A4017CQY은 설정을 잘 보여 주지만, stty -f /dev/cu.usbserial-A4017CQY -clocal과 같은 명령을 사용하여 설정을 변경하려고하면 stty을 연속해서 표시 할 때 변경된 것처럼 보입니다.

읽기/쓰기 전에 장치가 준비 될 때까지 대기하는 데 잠시 후 보고서를 쓸 수 있지만 읽지는 않겠다고보고합니다. 이 불만없이 완료되고 read()이 실패하는 방식으로이 메시지가 표시됩니다. 기록 된 데이터는 실제로 장치로 전송되지 않습니다.

나는이 문제를 디버깅하는 데 쓴 전체 테스트 프로그램은 다음과 같습니다 :

#include <stdio.h> 
#include <fcntl.h> 
#include <termios.h> 
#include <unistd.h> 
#include <sys/select.h> 

#define SYSCALL(A) do { ret = A; if (ret == -1) { perror(#A); return -1; } else printf("%s returned %d\n", #A, ret); } while (0) 
int ret; /* necessary for SYSCALL */ 

int main() 
{ 
    struct termios tio; 
    char buf[256]; 
    int fd = open("/dev/cu.usbserial-A4017CQY", 
      O_RDWR | O_NOCTTY | O_NONBLOCK); 
    fd_set rfds, wfds, xfds; 
    struct timeval to; 
    to.tv_sec = 5; 
    to.tv_usec = 0; 

    SYSCALL(tcgetattr(fd, &tio)); 

    cfmakeraw(&tio); 

    tio.c_cflag = CS8|CREAD|CLOCAL; 
    tio.c_cc[VMIN] = 1; 
    tio.c_cc[VTIME] = 1; 

    cfsetispeed(&tio, B115200); 
    cfsetospeed(&tio, B115200); 

    SYSCALL(tcsetattr(fd, TCSANOW, &tio)); 

    FD_ZERO(&rfds); 
    FD_ZERO(&wfds); 
    FD_ZERO(&xfds); 
    FD_SET(fd, &rfds); 
    FD_SET(fd, &wfds); 
    FD_SET(fd, &xfds); 

    int ret = select(fd+1, &rfds, NULL, &xfds, &to); 
    if (ret == -1) perror("select"); 
    else if (ret > 0) 
    { 
     if(FD_ISSET(fd, &rfds)) 
      puts("Ready to read"); 
     if(FD_ISSET(fd, &wfds)) 
      puts("Ready to write"); 
     if(FD_ISSET(fd, &xfds)) 
      puts("Exception!"); 
    } 
    else puts("Timed out!"); 

    SYSCALL(write(fd, "/home\n", 5)); 
    SYSCALL(read(fd, buf, 256)); 

    return 0; 
} 
+0

TL; DR : 잘못된 기기를 사용 중입니다. '/ dev/cu. * '가 아닌'/ dev/tty. *'를 사용하십시오. – duskwuff

답변

1

당신은 흐름 제어 문제가 있습니다. 케이블에서 RTS/CTS 및 DTR/DSR/CD를 루프백으로 조인하거나 다른 쪽에서 제어 신호를 제공하거나 @duskwuff에서 제시하는대로 흐름 제어를 무시하는 장치를 사용하십시오.

나는 당신이 CLOCAL을 설정하고있는 것을 볼 수 있습니다. - 작동해야하지만, 일부 USB 장치는 옳은 일을하지 않습니다. 귀하의 설명은 모뎀 제어 신호를 기다리는 장치와 일치합니다.