Как читать данные из последовательного порта в Linux с помощью C?

Я новичок в серийном программировании в Linux, используя C. Я нашел небольшой кусок кода для записи данных на последовательный порт, который я делюсь здесь. После запуска этого кода я могу предположить, что данные записаны на конкретном порту. Теперь я хотел бы открыть другой терминал и использовать отдельный код для чтения данных, написанных на этом конкретном порту, - как это сделать?

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

/*
 * 'open_port()' - Open serial port 1.
 *
 * Returns the file descriptor on success or -1 on error.
 */
int
open_port(void)
{
  int fd; /* File descriptor for the port */

  fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd == -1)
  {
   /* Could not open the port. */
    perror("open_port: Unable to open /dev/ttyS0 - ");
  }
  else
    fcntl(fd, F_SETFL, 0);

  n = write(fd, "ATZ\r", 4);
  if (n < 0)
    fputs("write() of 4 bytes failed!\n", stderr);

  return (fd);
}

Приведенный выше код будет записывать данные на конкретном порту.

Ответ 1

В теории все, что вам нужно сделать, это открыть соответствующий порт для чтения и использовать read() для получения данных.

int
read_port(void)
{
    int fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);
    if (fd == -1)
    {
        /* Could not open the port. */
        perror("open_port: Unable to open /dev/ttyS0 - ");
    }

    char buffer[32];
    int n = read(fd, buffer, sizeof(buffer));
    if (n < 0)
        fputs("read failed!\n", stderr);
    return (fd);
}

Существуют различия; в частности, чтению нужен буфер для ввода данных. Показанный код отбрасывает первое прочитанное сообщение. Обратите внимание, что короткое чтение просто указывает, что в то время, когда чтение было завершено, было меньше данных, чем было запрошено. Он автоматически не указывает на ошибку. Подумайте о командной строке; некоторые команды могут быть одним или двумя символами (ls), где другие могут быть довольно сложными (find /some/where -name '*.pdf' -mtime -3 -print). Тот факт, что один и тот же буфер используется для чтения, не является проблемой; один read дает 3 символа (включена новая строка), остальные 47 или около того.

Ответ 2

Выложенная программа делает много предположений о состоянии порта. В реальном приложении вы должны сделать все важные настройки явно. Я считаю, что лучшим источником обучения программированию последовательного порта в POSIX является

Руководство по серийному программированию для операционных систем POSIX

Я отражен здесь: https://www.cmrr.umn.edu/~strupp/serial.html