2013-04-02 4 views
5

USB 연결을 통해 PL2303 드라이버로 직렬 포트로 데이터를 읽는 중입니다. open을 수행 할 때 및 TTY 옵션과 비 차단을 설정할 때 성공적으로 반환됩니다. 연결을 닫으려고하면 연결이 끊어집니다. 이 상태에서는 문자 대신 " "라고 읽습니다.직렬 포트 연결을 닫을 때 프로그램이 중단됩니다.

나는 cutecom으로 완벽하게 장치에 연결할 수 있습니다.

  1. 내가 처음에는 cutecom (직렬 모니터)을 통해 장치에 연결하면 프로그램이 연결될 때마다 완벽하게 잘 닫힙니다. 문자가 읽히길 기대하면서 문자를 읽습니다. (아니오 ).
  2. 하드웨어를 분리했다가 다시 연결하면 cutecom을 실행할 때까지 프로그램이 다시 정지합니다.

cutecom을 사용한 후에 작동하므로 초기 연결 또는 연결 설정에 뭔가 빠져 있다고 생각합니다.

baud_rate = 38400; 
fd = open (device_path, O_RDONLY | O_NOCTTY); 

을 내 set_tty_options 함수에서 : : 여기에 연결하는 데 사용할 무엇

struct termios tty_options; 

memset (&tty_options, 0, sizeof(tty_options)); 
tcgetattr (fd, &tty_options); 

cfsetispeed(&tty_options, baud_rate);       // set baud rate 
tty_options.c_cflag = (tty_options.c_cflag & ~CSIZE) | CS8; // 8 bit msgs 
tty_options.c_cflag |= (CLOCAL | CREAD);      // enable reading 

tty_options.c_cflag &= ~(PARENB | PARODD);     // shut off parity 
tty_options.c_cflag |= parity; 
tty_options.c_cflag &= ~CSTOPB; 
tty_options.c_cflag &= ~CRTSCTS; 

if (tcsetattr (fd, TCSANOW, &tty_options) != 0) 
{ 
    printf("error %d from tcsetattr\n", errno); 
    return TTY_ERROR; 
} 

에서 set_blocking 기능 :

if (tcgetattr (fd, &tty) != 0) 
{ 
    printf("error %d from tggetattr", errno); 
    return FAILURE; 
} 

// 0 or 1 byte is enough to return from read 
tty.c_cc[VMIN] = should_block ? 1 : 0; 
tty.c_cc[VTIME] = 5;   // 0.5 seconds read timeout 

if (tcsetattr (fd, TCSANOW, &tty) != 0) 
{ 
    printf("error %d setting term attributes", errno); 
    return FAILURE; 
} 
+0

코드에 2 가지 문제점이 있음을 압니다. 첫째,'set_tty_options' 함수는'tty_options' 구조체를 완전히 초기화하지 않는 것 같습니다. 그것은 "내가 X를 먼저 실행하면 내 프로그램이 작동하지만 솔로 실행시 멈추거나 실패합니다."라고 설명 할 수 있습니다. 이는 환경을 적절하게 또는 완전히 초기화하지 않는 프로그램의 전형적인 증상입니다. 둘째,'set_blocking' 함수는 정규 입력에 대해 가짜입니다. 'c_cc [VMIN]'과'c_cc [VTIME]'은 ** 비표준 ** (raw) 입력에만 사용해야합니다. 정규 입력의 non-blocking'read()'를 위해,'fcntl()'을 사용하여 그것을 설정하십시오. – sawdust

답변

0

다음은 내가 한 일입니다. 나는 기본적으로 복사하고 붙여 넣기하여 cutecom's 소스 코드 에서이 알아 냈어. 내가 뭐하고 있었로

  1. 열기 ...

    int fd, n; 
    fd = open (device_path, O_RDONLY | O_NOCTTY | O_NDELAY); 
    
    ... error check fd ... 
    
    n = fcntl(ail_info->ail_serial_fd, F_GETFL, 0); 
    fcntl(fd, F_SETFL, n & ~O_NDELAY); 
    
  2. 당신은 전송 속도를 설정할 수 없습니다. 정의 된 B38400을 사용해야합니다.

    baud = B38400;

  3. 그럼, wallyk의 답변을했다.

편집

tty_settings.c_lflag = 0;

: 톱밥 코멘트 당, 나는 원시 입력으로 설정하는 더 좋은 방법을 발견했다.

tty_options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 

그리고 그것은 작동합니다.

+0

* "그런 다음 wallyk의 답변을 추가했습니다. tty_settings.c_lflag = 0;"* - 여전히 직렬 포트를 올바르게 구성하지 않았습니다. 'c_oflag'는 무엇으로 설정되어 있습니까? 'termios' 구조체 멤버에 대한 하드 할당은 POSIX별로 권장하지 않습니다. 당신은'tcgetattr()'을 호출 한 다음 ('c_cflag'처럼) 각 속성 필드를 활성화하거나 비활성화해야합니다. [POSIX 운영 체제 용 직렬 프로그래밍 안내서] (http://www.easysw.com/~mike/serial/serial.html)를 참조하십시오. POSIX 호출을 사용하고 있으므로 해당 규칙을 따르십시오. – sawdust

1

난 당신이 주장하는 오픈 플래그에 | O_SYNC을 추가 할 생각 동기 I/O에. 나는 그것이 문제를 일으키는 지 의심 스럽다. ,

tty_settings.c_iflag &= ~IGNBRK;   // ignore break signal 

는 또한, 당신은 입력 처리가 완전히 해제되어 있는지 확인하려면 :

그러나, 나는 당신이지고 같은 NUL 문자로보고 브레이크 신호를 무시하려는 생각 그래서 백 스페이스의 영수증,^C는^\ 등 어떤 반응을 유발하지 않는 : 그 괜찮해야한다, 그래서 당신은 이미, my set_blocking() function를 사용하는 것처럼

tty_settings.c_lflag = 0;    // no signaling chars, no echo, 
             // no canonical processing 

것 같습니다.