Is it possible to have two separate one way (simplex) serial ports to make single tty device

embeddedserial portserial-consoleudevusb

I am building an embedded device which has IR communication with PC and it will have two IR Led/detector pairs which are one-way and are setup like this:
IR source input commands -> near embedded device located detector for receiving commands, IR source near embedded for monitoring output -> detector near output for external device to get monitoring data.

I found that the simplest method to implement in hardware is to have separate one-way serial communication ports for each IR/detector pair: first for sending commands, second for monitoring output.

In my Linux PC box I have these two separate serial ports listed as, say /dev/ttyUSB1 and /dev/ttyUSB2.
What I want is to have one ttyUSB act as an input, other as output, but be able to access both with terminal as single two-way port.

Virtual device solution on /dev/ should be enough, but is not must, the possibility to make program like minicom (or its substitute) to react on two separate ports without any new virtual devices would suffice.

The problem is only on PC side and I think should be solved in software: if there is no solution to this problem I will probably add some custom hardware multiplexing/buffering to make single communication port from these two.

Edit: I added (rather rough draft) image for better illustration where is my problem:
enter image description here

Best Answer

I would use LD_PRELOAD and a dynamic library (you have to create it) to override the calls that minicom do, open(), read(), write(), ioctl(), close(), I don't think are much more.

google for "ld_preload override" you should find ton of examples about the technique.

  • use the command strace with minicom to see the calls it does
  • start overriding the open() in your library
  • define a tty device name that doesn't exist, eg: /dev/mytty
  • then run minicom over this tty
  • in your open() implementation match this device name
    • if it match then you must open your real ttyUSB pair
    • if it doesn't match fallback to the real open()

the library will replace all the open() called by minicom, so for the unmatching filename you must fallback to the real (not only for open() but for all the calls that you override).

return a valid file descriptor if you opened your tty pair successfully, else an error.
With this file descriptor, in the library, you want to associate more info (eg: the two file descriptor of your real tty).

For the others calls what you have to match is the file descriptor, if it match the one returned from open then the call is for /dev/mytty, if it is a write() you want to call a real write() on your ttyUSB1, if it is a read() a real read() on ttyUSB2. If the descriptor doesn't match fallback to the real call.

The ioctl() could be the non-trivial, maybe some ioctl need to go to your read device and some to the write device, some to both... depend by the ioctl arguments.

EDIT

Probably a well-done terminal like minicom use a non-blocking approach, so you'll have to wrap calls like select() or poll() which surely add some complexity, but I think still easier than getting a kernel driver or rework the hardware.

EDIT

This ttypersist solve a different problem using the same technique.

Related Question