我有一个 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,则意味着您拥有一个网络连接:它根本没有说明任何有关连接状态的信息连续剧联系。