从 ttyS0 读取和写入

从 ttyS0 读取和写入

我有一个 Raspberry PI Zero W 通过 USB 连接到我的虚拟机,可以/dev/ttyS0在 PC 和 RPI 下找到。目前我正在尝试通过 USB 电缆将一些内容从 RPI 发送到虚拟机 (PC)。

我正在尝试使用以下代码读取端口:

    #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 程序都在连续循环中运行,但我在 PC 端没有收到任何信息。

可能是什么原因?

笔记: RPI 可以通过 USB 从虚拟机访问,因为我在虚拟机上使用 SSH 来访问 RPI。所以是的,VM 应该已经配置为访问 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 串行转换器驱动程序生成的串行端口连接到 VM /dev/ttyS0:如果这是真的,那么这可能会在 PC 端工作。但那就是不是默认值:您必须在虚拟化软件中进行配置,否则它将无法工作。

更常见的配置是配置虚拟化软件以允许虚拟机整体访问 USB 串行转换器的 USB 端:然后它将在虚拟机中显示为类似的内容/dev/ttyUSB0(取决于串行转换器的确切类型)转换器)。

在RasPi方面,/dev/ttyS0 不存在在 Pi Zero W 的默认配置中 - 典型的串行端口是/dev/ttyAMA0,但在默认配置中它由蓝牙功能使用。如果您已将 USB 串行转换器的 USB 端插入 RasPi,那么它也会显示为/dev/ttyUSB0此处。

由于您的 RasPi 端脚本不会检查设备是否存在,因此它可能创建了一个名为 的文件,其中/dev/ttyS0包含一行带有数字的文件。1在 RasPi 上运行此命令以查看其是否/dev/ttyS0是有效的串行设备:

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

如果您在 RasPi 端使用物理串行连接(/dev/ttyS0/dev/ttyAMA0),据我所知,您应该在 RasPi Zero W 上焊接 40 针连接器,并将某些东西插入该连接器的针脚 8 和 10。您还必须使用raspi-config来启用串行端口访问。

如果您可以通过 SSH 访问 RasPi,则意味着您拥有一个网络连接:它根本没有说明任何有关连接状态的信息连续剧联系。

相关内容