Lectura y escritura desde/hacia ttyS0

Lectura y escritura desde/hacia ttyS0

Tengo una Raspberry PI Zero W conectada a mi máquina virtual a través de USB, que se puede encontrar /dev/ttyS0tanto en PC como en RPI. Actualmente estoy intentando enviar algo desde el RPI a través del cable USB a la máquina virtual (PC).

Estoy intentando leer en el puerto con el siguiente código:

    #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;
  }

y en el lado de RPI, hice un pequeño script bash, que envía el carácter 1:

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

Sin embargo, aunque el script bash y el programa c se ejecutan en bucles continuos, no recibo nada en la PC.

¿Cuál podría ser la razón?

NOTA: Se puede acceder al RPI a través de USB desde la VM, ya que estoy usando SSH en la VM para acceder al RPI. Entonces sí, la VM ya debería estar configurada para acceder al puerto USB.

EDITAR: Intenté cambiar el código a este, donde implementé la función read(), sin embargo todavía no veo ningún cambio:

    #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;
  }

Respuesta1

En su edición, agregó el código para leer desde el puerto a la open_port()función. Si bien parece que podría funcionar, es de mal estilo: ahora la open_port()función es específica para las necesidades de este programa y ya no es fácil de seleccionar y reutilizar en algún proyecto futuro sin modificaciones. Y el nombre de la función ya no describe con precisión lo que hace la función.

No estoy convencido de que la configuración de su conexión serie sea correcta: dice que está usando una máquina virtual y que hay un USB involucrado, pero parece que lo está usando /dev/ttyS0en ambos extremos. Eso se refiere a un puerto serie físico, no a uno basado en USB.

Tal vez haya configurado su software de virtualización para conectar un puerto serie físico real o un puerto serie generado por el controlador convertidor USB-serie del host a la máquina virtual./dev/ttyS0 : si eso es cierto, entonces podría funcionar en el lado de la PC. Pero eso esno es el predeterminado: definitivamente debes configurar eso en tu software de virtualización o de lo contrario no funcionará.

Una configuración más común sería configurar el software de virtualización para permitir que la VM acceda al lado USB de un convertidor USB-serie como un todo: entonces aparecería en la VM como algo así /dev/ttyUSB0(dependiendo del tipo exacto de la serie convertidor).

En el lado de RasPi,/dev/ttyS0 no existeen la configuración predeterminada del Pi Zero W, el puerto serie típico es /dev/ttyAMA0, pero en la configuración predeterminada lo utiliza la funcionalidad Bluetooth. Si ha conectado el lado USB del convertidor serie USB al RasPi, aparecerá como /dev/ttyUSB0aquí también.

Dado que su script del lado RasPi no verifica la existencia del dispositivo, es posible que haya creado un archivo llamado /dev/ttyS0, que contiene una sola línea con un número 1. Ejecute este comando en RasPi para ver si /dev/ttyS0es un dispositivo serie válido:

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

Si está utilizando una conexión en serie física ( /dev/ttyS0o /dev/ttyAMA0) en el lado de RasPi, debe tener un conector de 40 pines en el RasPi Zero W soldado y algo conectado a los pines 8 y 10 de ese conector, según tengo entendido. También habría tenido que utilizar raspi-configpara habilitar el acceso al puerto serie.

Si puedes acceder a RasPi con SSH, eso significa que tienes unredconexión: no dice nada en absoluto sobre el estado de unde serieconexión.

información relacionada