Linux 虚拟串口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/52187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:24:34  来源:igfitidea点击:

Virtual Serial Port for Linux

linuxserial-portvirtual-serial-port

提问by JeffV

I need to test a serial port application on Linux, however, my test machine only has one serial port.

我需要在Linux上测试一个串口应用程序,但是我的测试机只有一个串口。

Is there a way to add a virtual serial port to Linux and test my application by emulating a device through a shell or script?

有没有办法将虚拟串口添加到 Linux 并通过 shell 或脚本模拟设备来测试我的应用程序?

Note: I cannot remap the port, it hard coded on ttys2 and I need to test the application as it is written.

注意:我无法重新映射端口,它在 ttys2 上进行了硬编码,我需要在编写应用程序时对其进行测试。

采纳答案by apenwarr

You can use a pty ("pseudo-teletype", where a serial port is a "real teletype") for this. From one end, open /dev/ptyp5, and then attach your program to /dev/ttyp5; ttyp5will act just like a serial port, but will send/receive everything it does via /dev/ptyp5.

为此,您可以使用 pty(“伪电传打字机”,其中串行端口是“真正的电传打字机”)。从一端打开/dev/ptyp5,然后将您的程序附加到/dev/ttyp5; ttyp5将像串行端口一样工作,但将通过 /dev/ptyp5 发送/接收它所做的一切。

If you really need it to talk to a file called /dev/ttys2, then simply move your old /dev/ttys2out of the way and make a symlink from ptyp5to ttys2.

如果您真的需要它与名为 的文件通信/dev/ttys2,那么只需将您的旧文件移开/dev/ttys2并从ptyp5to建立符号链接ttys2

Of course you can use some number other than ptyp5. Perhaps pick one with a high number to avoid duplicates, since all your login terminals will also be using ptys.

当然,您可以使用除ptyp5. 也许选择一个数字大的以避免重复,因为您所有的登录终端也将使用 ptys。

Wikipedia has more about ptys: http://en.wikipedia.org/wiki/Pseudo_terminal

维基百科有更多关于 ptys:http: //en.wikipedia.org/wiki/Pseudo_terminal

回答by Howler

Would you be able to use a USB->RS232 adapter? I have a few, and they just use the FTDI driver. Then, you should be able to rename /dev/ttyUSB0 (or whatever gets created) as /dev/ttyS2 .

您可以使用 USB->RS232 适配器吗?我有几个,他们只使用 FTDI 驱动程序。然后,您应该能够将 /dev/ttyUSB0 (或创建的任何内容)重命名为 /dev/ttyS2 。

回答by Adam Davis

I can think of three options:

我能想到三个选项:

Implement RFC 2217

实施 RFC 2217

RFC 2217covers a com port to TCP/IP standard that allows a client on one system to emulate a serial port to the local programs, while transparently sending and receiving data and control signals to a server on another system which actually has the serial port. Here's a high-level overview.

RFC 2217涵盖到 TCP/IP 标准的 com 端口,该标准允许一个系统上的客户端模拟本地程序的串行端口,同时透明地向实际具有串行端口的另一个系统上的服务器发送和接收数据和控制信号。这是一个高级概述

What you would do is find or implement a client com port driver that would implement the client side of the system on your PC - appearing to be a real serial port but in reality shuttling everything to a server. You might be able to get this driver for free from Digi, Lantronix, etc in support of their real standalone serial port servers.

您要做的是找到或实现一个客户端 com 端口驱动程序,该驱动程序将在您的 PC 上实现系统的客户端 - 看起来是一个真正的串行端口,但实际上将所有东西都传送到服务器。您可以从 Digi、Lantronix 等免费获得此驱动程序,以支持他们真正的独立串行端口服务器。

You would then implement the server side of the connection locally in another program - allowing the client to connect and issuing the data and control commands as needed.

然后,您将在另一个程序中本地实现连接的服务器端 - 允许客户端连接并根据需要发出数据和控制命令。

It's probably non trivial, but the RFC is out there, and you might be able to find an open source project that implements one or both sides of the connection.

这可能很重要,但是 RFC 就在那里,您可能能够找到一个实现连接的一侧或两侧的开源项目。

Modify the linux serial port driver

修改linux串口驱动

Alternately, the serial port driver source for Linux is readily available. Take that, gut the hardware control pieces, and have that one driver run two /dev/ttySx ports, as a simple loopback. Then connect your real program to the ttyS2 and your simulator to the other ttySx.

或者,Linux 的串行端口驱动程序源很容易获得。拿它来说,去掉硬件控制部分,让一个驱动程序运行两个 /dev/ttySx 端口,作为一个简单的环回。然后将您的真实程序连接到 ttyS2,将您的模拟器连接到另一个 ttySx。

Use two USB<-->Serial cables in a loopback

在环回中使用两个 USB<--> 串行电缆

But the easiest thing to do right now? Spend $40 on two serial port USB devices, wire them together (null modem) and actually have two real serial ports - one for the program you're testing, one for your simulator.

但是现在最简单的事情是什么?在两个串行端口 USB 设备上花费 40 美元,将它们连接在一起(空调制解调器),实际上有两个真正的串行端口 - 一个用于您正在测试的程序,一个用于您的模拟器。

-Adam

-亚当

回答by apenwarr

You may want to look at Tibbo VSPDLfor creating a linux virtual serial port using a Kernel driver -- it seems pretty new, and is available for download right now (beta version). Not sure about the license at this point, or whether they want to make it available commercially only in the future.

您可能想查看Tibbo VSPDL以使用内核驱动程序创建 linux 虚拟串行端口——它看起来很新,现在可以下载(测试版)。目前不确定许可证,或者他们是否只想在未来将其商业化。

There are other commercial alternatives, such as http://www.ttyredirector.com/.

还有其他商业替代品,例如http://www.ttyredirector.com/

In Open Source, Remserial(GPL) may also do what you want, using Unix PTY's. It transmits the serial data in "raw form" to a network socket; STTY-like setup of terminal parameters must be done when creating the port, changing them later like described in RFC 2217 does not seem to be supported. You should be able to run two remserial instances to create a virtual nullmodem like com0com, except that you'll need to set up port speed etc in advance.

在开源中,Remserial(GPL) 也可以使用 Unix PTY 做你想做的事。它以“原始形式”将串行数据传输到网络套接字;在创建端口时必须完成类似 STTY 的终端参数设置,稍后像 RFC 2217 中描述的那样更改它们似乎不受支持。您应该能够运行两个 remserial 实例来创建像 com0com 这样的虚拟空调制解调器,但您需要提前设置端口速度等。

Socat(also GPL) is like an extended variant of Remserial with many many more options, including a "PTY" method for redirecting the PTY to something else, which can be another instance of Socat. For Unit tets, socat is likely nicer than remserial because you can directly cat files into the PTY. See the PTY exampleon the manpage. A patch existsunder "contrib" to provide RFC2217 support for negotiating serial line settings.

Socat(也是 GPL)就像 Remserial 的扩展变体,有更多的选项,包括用于将 PTY 重定向到其他东西的“PTY”方法,它可以是 Socat 的另一个实例。对于 Unit tets,socat 可能比 remserial 更好,因为您可以直接将文件 cat 放入 PTY。请参阅联机帮助页上的PTY 示例。“contrib”下存在一个补丁,为协商串行线路设置提供 RFC2217 支持。

回答by Mauro Ciancio

Using the links posted in the previous answers, I coded a little example in C++ using a Virtual Serial Port. I pushed the code into GitHub: https://github.com/cymait/virtual-serial-port-example.

使用之前答案中发布的链接,我使用虚拟串行端口在 C++ 中编写了一个小示例。我将代码推送到 GitHub:https: //github.com/cymait/virtual-serial-port-example

The code is pretty self explanatory. First, you create the master process by running ./main master and it will print to stderr the device is using. After that, you invoke ./main slave device, where device is the device printed in the first command.

代码是不言自明的。首先,您通过运行 ./main master 创建主进程,它将打印到设备正在使用的 stderr。之后,您调用 ./main slave device,其中 device 是第一个命令中打印的设备。

And that's it. You have a bidirectional link between the two process.

就是这样。您在两个进程之间建立了双向链接。

Using this example you can test you the application by sending all kind of data, and see if it works correctly.

使用此示例,您可以通过发送所有类型的数据来测试您的应用程序,并查看它是否正常工作。

Also, you can always symlink the device, so you don't need to re-compile the application you are testing.

此外,您始终可以对设备进行符号链接,因此您无需重新编译正在测试的应用程序。

回答by slonik

Use socat for this:

为此使用 socat:

For example:

例如:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11

回答by Peter Remmers

There is also tty0tty http://sourceforge.net/projects/tty0tty/which is a real null modem emulator for linux.

还有 tty0tty http://sourceforge.net/projects/tty0tty/这是一个真正的 Linux 空调制解调器模拟器。

It is a simple kernel module - a small source file. I don't know why it only got thumbs down on sourceforge, but it works well for me. The best thing about it is that is also emulates the hardware pins (RTC/CTS DSR/DTR). It even implements TIOCMGET/TIOCMSET and TIOCMIWAIT iotcl commands!

它是一个简单的内核模块——一个小的源文件。我不知道为什么它只对 sourceforge 嗤之以鼻,但它对我来说效果很好。最好的一点是它还可以模拟硬件引脚(RTC/CTS DSR/DTR)。它甚至实现了 TIOCMGET/TIOCMSET 和 TIOCMIWAIT iotcl 命令!

On a recent kernel you may get compilation errors. This is easy to fix. Just insert a few lines at the top of the module/tty0tty.c source (after the includes):

在最近的内核上,您可能会遇到编译错误。这很容易修复。只需在 module/tty0tty.c 源代码的顶部插入几行(在包含之后):

#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif

When the module is loaded, it creates 4 pairs of serial ports. The devices are /dev/tnt0 to /dev/tnt7 where tnt0 is connected to tnt1, tnt2 is connected to tnt3, etc. You may need to fix the file permissions to be able to use the devices.

当模块加载时,它会创建 4 对串口。这些设备是 /dev/tnt0 到 /dev/tnt7,其中 tnt0 连接到 tnt1,tnt2 连接到 tnt3 等。您可能需要修复文件权限才能使用这些设备。

edit:

编辑:

I guess I was a little quick with my enthusiasm. While the driver looks promising, it seems unstable. I don't know for sure but I think it crashed a machine in the office I was working on from home. I can't check until I'm back in the office on monday.

我想我的热情有点快了。虽然驱动程序看起来很有希望,但它似乎不稳定。我不确定,但我认为它使我在家工作的办公室的一台机器崩溃了。星期一我回到办公室之前,我无法检查。

The second thing is that TIOCMIWAIT does not work. The code seems to be copied from some "tiny tty" example code. The handling of TIOCMIWAIT seems in place, but it never wakes up because the corresponding call to wake_up_interruptible() is missing.

第二件事是 TIOCMIWAIT 不起作用。该代码似乎是从一些“小 tty”示例代码中复制而来的。TIOCMIWAIT 的处理似乎到位,但它永远不会唤醒,因为缺少对wake_up_interruptible() 的相应调用。

edit:

编辑:

The crash in the office really was the driver's fault. There was an initialization missing, and the completely untested TIOCMIWAIT code caused a crash of the machine.

办公室里的车祸确实是司机的错。缺少初始化,完全未经测试的 TIOCMIWAIT 代码导致机器崩溃。

I spent yesterday and today rewriting the driver. There were a lot of issues, but now it works well for me. There's still code missing for hardware flow control managed by the driver, but I don't need it because I'll be managing the pins myself using TIOCMGET/TIOCMSET/TIOCMIWAIT from user mode code.

我昨天和今天都在重写驱动程序。有很多问题,但现在对我来说效果很好。驱动程序管理的硬件流控制仍然缺少代码,但我不需要它,因为我将使用来自用户模式代码的 TIOCMGET/TIOCMSET/TIOCMIWAIT 自己管理引脚。

If anyone is interested in my version of the the code, send me a message and I'll send it to you.

如果有人对我的代码版本感兴趣,请给我发消息,我会发送给您。

回答by cantoni

Complementing the @slonik's answer.

补充@slonik 的回答。

You can test socat to create Virtual Serial Port doing the following procedure (tested on Ubuntu 12.04):

您可以按照以下步骤测试 socat 以创建虚拟串行端口(在 Ubuntu 12.04 上测试):

Open a terminal (let's call it Terminal 0) and execute it:

打开一个终端(我们称之为终端 0)并执行它:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

The code above returns:

上面的代码返回:

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]

Open another terminal and write (Terminal 1):

打开另一个终端并写入(终端 1):

cat < /dev/pts/2

this command's port name can be changed according to the pc. it's depends on the previous output.

这个命令的端口名可以根据pc改变。这取决于之前的输出。

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs 

you should use the number available on highlighted area.

您应该使用突出显示区域上可用的数字。

Open another terminal and write (Terminal 2):

打开另一个终端并写入(终端 2):

echo "Test" > /dev/pts/3

Now back to Terminal 1 and you'll see the string "Test".

现在回到终端 1,您将看到字符串“Test”。