2013-09-05 2 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()'), вы, вероятно, должны использовать канонический, а не сырой режим. – sawdust

ответ

0

@randomization, я думаю, вы должны настроить управляющие символы, т.е. c_cc [VTIME] и c_cc [VMIN]. VTIME: Таймер запускается при вызове чтения. read возвращает либо когда имеется хотя бы один байт данных, либо по истечении таймера. Если таймер истекает без ввода каких-либо входных данных, считывание возвращает 0. VMIN: считывает блоки до тех пор, пока не будет доступно меньшее количество MIN байтов или количество запрошенных байтов, и возвращает меньшее из этих двух значений. Попробуйте настроить VMIN и VTIME и протестировать приложение. Вы можете настроить любой из них. Найдете хорошее описание об этих вещах в man-страницах, то есть #man termios.

+0

Да, VTIME и VMIN не должны оставаться неуказанными при использовании неканонического режима. Но ваши объяснения таймера и того, как/когда 'read()' вернутся, неверны. Вы упростили работу этих конфигураций без указания значений. НАПРИМЕР. таймер может быть от начала вызова (как вы упоминаете), или межсимвольного таймера или вообще нет таймера. OP видит ожидаемое поведение для значений по умолчанию для VMIN и VTIME. – sawdust

+0

@sawdust, информация о VTIME и VMIN и о его возвращаемых значениях приведены на странице man termios. –

Смежные вопросы