2013-09-05 4 views
2

아래 코드는 두 번째 직렬 포트를 열어 읽고 쓰려고합니다. 이제 첫 번째 포트 (Tera Term Console)에서 콘솔 기능을 사용하고 있습니다. 거기에 기록합니다 (printf 또는 dmesg).직렬 포트 (UART)를 읽을 수 없습니다

하지만 포트에서 읽을 수 없습니다. 콘솔이 정지합니다.

int fd; /* File descriptor for the port */ 
    #define BUFF_SIZE 1024 
    struct termios options; 
    char to_write[1024]; 
    char to_read[1024]; 
    int bytes_written; 

    int init_uart() 
    { 
     tcgetattr(fd, &options); 

     /* Set Baud Rate */ 

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

     // Set the Charactor size 

     options.c_cflag &= ~CSIZE; /* Mask the character size bits */ 
     options.c_cflag |= CS8; /* Select 8 data bits */ 

     // Set parity - No Parity (8N1) 

     options.c_cflag &= ~PARENB;/*no parity bit*/ 
     options.c_cflag &= ~CSTOPB;/* One bit stop bit*/ 
     options.c_cflag &= ~CSIZE; 
     options.c_cflag |= CS8;/* 8 Bits Character length*/ 

     // Disable Hardware flowcontrol 
     options.c_cflag &= ~CRTSCTS; 

     // Enable Raw Input 
     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 

     // Disable Software Flow control 
     options.c_iflag &= ~(IXON | IXOFF | IXANY); 

     // Chose raw (not processed) output 
     options.c_oflag &= ~OPOST; 

     if (tcsetattr(fd, TCSANOW, &options) == -1){ 
      printf ("Error with tcsetattr = %s\n", strerror (errno)); 
      return -1; 
     } 
     return 0; 
    } 
    int write_uart() 
    { 
     int i=0; 
     while (i < BUFF_SIZE-2){ 
      to_write[i]='a'; 
      i++; 
     } 
     to_write[i]='\n'; 
     to_write[i+1]='\r'; 
     // Write to the port 
     bytes_written = write(fd, to_write, BUFF_SIZE); 

     if(bytes_written < BUFF_SIZE){ 
      fputs("write() of 1024 bytes failed!\n", stderr); 
      return -1; 
     } 
     return 0; 
    } 

    int 
    read_port(void) 
    { 
     int n = read(fd, to_read, sizeof(BUFF_SIZE)); 
     if (n < 1024){ 
      fputs("read failed!\n", stderr); 
      return -1; 
     } 
     return 0; 
    } 

    int main() 
    { 
     int i=0; 
     fd = open("/dev/ttyS1",O_RDWR | O_NOCTTY); 
     if(fd == -1) 
      perror("open_port: Unable to open /dev/ttyS1\n"); 
     else 
      printf("ttyS0 Opened successfully\n"); 
     if(init_uart()) 
      perror("open_port: Unable to initialize /dev/ttyS0 Port\n"); 
     else 
      printf("Port Initialization is done successfuly\n"); 
     if(write_uart()) 
      perror("write_port: Unable to write to /dev/ttyS0 Port\n"); 
     else 
      printf("Write to the port happened successfully\n"); 
     if(read_port()) 
      perror("read_port: Unable to read from /dev/ttyS0 Port\n"); 
     else 
      printf("Read to the port happened successfully\n"); 
     close(fd); 
    return 0; 
    } 
+0

올바른 POSIX 초기화 및 리턴 코드 검사를 사용하는 직렬 포트 질문을보기에 좋습니다. 그러나 (1)'tcgetattr()'의 리턴 코드를 체크하는 것을 잊었습니다. (2)이 직렬 포트는 어떤 장치에 연결되어 있습니까? 직렬 링크의 다른 끝에 장치가 없다면 무엇을 읽을 것으로 예상합니까? (3) 포트를 원시 모드로 설정 하시겠습니까? 연결된 장치 (?)에 따라 정식 모드가 필요할 수도 있고 필요할 수도 있습니다. 텍스트 디바이스 ('write()'출력이 나타내는 것처럼)라면 raw 모드 대신 canonical을 사용해야합니다. – sawdust

답변

0

@randomization, 난 당신이 제어 문자를 구성 할 수 있다고 생각 즉 c_cc [VTIME]과 c_cc [VMIN]. VTIME : 읽기가 호출되면 타이머가 시작됩니다. read는 적어도 한 바이트의 데이터를 사용할 수 있거나 타이머가 만료 될 때 반환됩니다. 타이머가 만료되지 않고 만료되면 0을 반환합니다. VMIN : MIN 바이트 중 작은 바이트 또는 요청 된 바이트 수를 사용할 수있을 때까지 블록을 읽은 다음이 두 값 중 작은 값을 반환합니다. VMIN 및 VTIME 구성을 시도하고 응용 프로그램을 테스트하십시오. 둘 중 하나를 구성 할 수 있습니다. 맨 페이지 (예 : #man termios)에서 이러한 것들에 대한 좋은 설명을 찾을 수 있습니다.

+0

예, 비표준 모드를 ​​사용할 때 VTIME 및 VMIN을 지정하지 않아야합니다. 그러나 타이머에 대한 설명과'read()'가 언제/언제 리턴 할지는 틀린 것입니다. 값을 지정하지 않고 이러한 구성이 작동하는 방식을 단순화했습니다. E.G. 타이머는 통화의 시작 (언급 한대로) 또는 문자 간 타이머 또는 타이머 없음으로 할 수 있습니다. OP는 VMIN 및 VTIME의 기본값에 대해 예상되는 동작을보고 있습니다. – sawdust

+0

@ 톱밥, VTIME과 VMIN에 대한 설명과 반환 값에 대해서는 termios의 맨 페이지에서 가져온 것입니다. –