Чтение и запись с/на ttyS0

Чтение и запись с/на ttyS0

У меня есть Raspberry PI Zero W, подключенный к моей виртуальной машине через USB, который можно найти /dev/ttyS0как на ПК, так и на RPI. В настоящее время я пытаюсь отправить что-то с RPI через USB-кабель на виртуальную машину (ПК).

Я пытаюсь прочитать через порт с помощью следующего кода:

    #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 fd; /* File descriptor for the port */

   int open_port(void)    
   {            
     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, FNDELAY);      

    return (fd);    
  }

  int close_port(void)
  {
    close(fd);
    return (fd);
  }


  int main()
  {
    printf("Serial reader has started...\n\n");
    while(1)
    {
      open_port();
      close_port();
    }

    return 0;
  }

а на стороне RPI я создал небольшой bash-скрипт, который отправляет символ 1:

while :
do
    echo "sending character 1 to /dev/ttyS0"
    echo "1" > /dev/ttyS0
done

Однако, несмотря на то, что скрипт bash и программа c работают в непрерывных циклах, я ничего не получаю на стороне ПК.

Что может быть причиной?

ПРИМЕЧАНИЕ: RPI доступен через USB с виртуальной машины, поскольку я использую SSH на виртуальной машине для доступа к RPI. Так что да, виртуальная машина уже должна быть настроена для доступа к порту USB.

РЕДАКТИРОВАТЬ: Я попробовал изменить код на этот, где я реализовал функцию read(), однако никаких изменений я все еще не вижу:

    #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 fd; /* File descriptor for the port */
   unsigned char bufptr;
   int reader;

   int open_port(void)    
   {            
     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, FNDELAY);
      reader = read(fd, &bufptr, 1);
        if (reader > 0)
        {
          write(STDOUT_FILENO, &bufptr, 1);  
        }
     }

    return (fd);    
  }

  int close_port(void)
  {
    close(fd);
    return (fd);
  }


  int main()
  {
    printf("Serial reader has started...\n\n");
    while(1)
    {
      open_port();
      close_port();
    }

    return 0;
  }

решение1

В своем редактировании вы добавили код для чтения из порта в open_port()функцию. Хотя это выглядит так, как будто это может работать, это плохой стиль: теперь функция open_port()специфична для нужд этой программы и ее больше нелегко выбрать и повторно использовать в каком-то будущем проекте без изменений. И имя функции больше не описывает точно, что она делает.

Я не уверен, что настройка вашего последовательного соединения верна: вы говорите, что используете виртуальную машину и что USB задействован, но вы, похоже, используете /dev/ttyS0на обоих концах. Это относится к физическому последовательному порту, а не к основанному на USB.

Возможно, вы настроили свое программное обеспечение виртуализации для подключения реального физического последовательного порта или последовательного порта, сгенерированного драйвером USB-последовательного преобразователя хоста, к виртуальной машине /dev/ttyS0: если это правда, то это может работать на стороне ПК. Но этоне по умолчанию: вам обязательно нужно настроить это в вашем программном обеспечении для виртуализации, иначе ничего не будет работать.

Более распространенной конфигурацией будет настройка программного обеспечения виртуализации таким образом, чтобы разрешить виртуальной машине получать доступ к USB-стороне USB-последовательного преобразователя в целом: тогда в виртуальной машине он будет отображаться как нечто вроде /dev/ttyUSB0(в зависимости от точного типа последовательного преобразователя).

Со стороны RasPi,/dev/ttyS0 не существуетв конфигурации по умолчанию Pi Zero W - типичный последовательный порт - /dev/ttyAMA0, но в конфигурации по умолчанию он используется функциональностью Bluetooth. Если вы подключили USB-сторону USB-последовательного преобразователя к RasPi, то он /dev/ttyUSB0также будет отображаться здесь.

Поскольку ваш скрипт на стороне RasPi не проверяет существование устройства, он мог создать файл с именем /dev/ttyS0, содержащий одну строку с номером 1. Запустите эту команду на RasPi, чтобы проверить, /dev/ttyS0является ли это допустимым последовательным устройством:

 test -c /dev/ttyS0 && echo "Maybe valid" || echo "Definitely not correct"

Если вы используете физическое последовательное соединение ( /dev/ttyS0или /dev/ttyAMA0) на стороне RasPi, у вас должен быть припаян 40-контактный разъем на RasPi Zero W, и что-то подключено к контактам 8 и 10 этого разъема, насколько я понимаю. Вам также пришлось бы использовать raspi-configдля включения доступа к последовательному порту.

Если вы можете получить доступ к RasPi по SSH, это значит, что у вас естьсетьсвязь: это вообще ничего не говорит о состояниисерийныйсвязь.

Связанный контент