我正在构建一个与 PC 进行红外通信的嵌入式设备,它将有两个单向 IR Led/探测器对,设置如下:IR 源输入命令 -> 位于嵌入式设备附近的用于接收命令的探测器、IR 源近嵌入式用于监控输出 -> 检测器近输出用于外部设备获取监控数据。
我发现在硬件中实现的最简单方法是为每个 IR/探测器对配备单独的单向串行通信端口:第一个用于发送命令,第二个用于监视输出。
在我的 Linux PC 机箱中,我将这两个单独的串行端口列为/dev/ttyUSB1
和/dev/ttyUSB2
。我想要的是让一个 ttyUSB 作为输入,另一个作为输出,但能够通过终端作为单个双向端口访问这两个端口。
虚拟设备解决方案/dev/
应该足够了,但不是必须的,让像 minicom(或其替代品)这样的程序在两个独立的端口上做出反应而不需要任何新的虚拟设备就足够了。
问题仅出现在 PC 端,我认为应该在软件中解决:如果这个问题没有解决方案,我可能会添加一些自定义硬件多路复用/缓冲,以从这两个端口创建单个通信端口。
编辑:我添加了(相当粗糙的草稿)图像,以便更好地说明我的问题在哪里:
答案1
我会使用一个动态库(LD_PRELOAD
你必须创建它)来覆盖 minicom 所做的调用,open()
我认为没有更多。read()
write()
ioctl()
close()
谷歌搜索“ld_preload override”,你应该会找到大量有关该技术的示例。
- 使用 minicom 命令
strace
来查看它所做的调用 - 开始覆盖
open()
你的库中的 - 定义一个不存在的 tty 设备名称,例如:
/dev/mytty
- 然后通过这个 tty 运行 minicom
- 在您的
open()
实现中匹配此设备名称- 如果匹配,那么您必须打开真正的 ttyUSB 对
- 如果它不匹配回退到真实的
open()
该库将替换所有open()
由 minicom 调用的库,因此对于不匹配的文件名,您必须回退到真实值(不仅针对open()
您覆盖的所有调用)。
如果成功打开 tty 对,则返回有效的文件描述符,否则返回错误。
通过这个文件描述符,在库中,您想要关联更多信息(例如:真实 tty 的两个文件描述符)。
对于其他调用,您必须匹配的是文件描述符,如果它与从 open 返回的文件描述符匹配,则调用为 for /dev/mytty
,如果它是 a,则write()
您想write()
在 ttyUSB1 上调用 real,如果它是ttyUSB2 上的read()
real read()
。如果描述符与实际调用不匹配,则回退到实际调用。
这ioctl()
可能是不平凡的,也许一些 ioctl 需要去你的读设备,一些去写设备,一些去两者......取决于 ioctl 参数。
编辑
可能像 minicom 这样做得好的终端使用非阻塞方法,所以你必须包装像select()
或这样的调用poll()
,这肯定会增加一些复杂性,但我认为仍然比获取内核驱动程序或重新设计硬件更容易。
编辑
这打字坚持使用相同的技术解决不同的问题。