socat에서 직렬 장치 분리를 시뮬레이션하는 방법

socat에서 직렬 장치 분리를 시뮬레이션하는 방법

이 테스트 프로그램이 있어요

import sys

for line in sys.stdin:
    print(line.strip())

print("DONE")

실제 장치(FTDI)에서 라인을 인쇄하도록 하면

python3 demo.py < /dev/ttyUSB0

그런 다음 내가 보내는 모든 줄을 인쇄한 다음 USB 케이블을 뽑으면 DONE메시지가 표시됩니다.

반면에 socat을 사용하여 가짜 tty를 생성하면

socat -d -d pty,raw,echo=0,link=ttyFake pty,raw,echo=0,link=ttyFake.interface

그런 다음 Python 프로그램을 사용하여 가짜 장치를 모니터링합니다.

python3 demo.py < ttyFake

이렇게 메시지를 보낼 수 있어요

echo test >> ttyFake.interface

인쇄되어 있어요

그러나 SIGINT 또는 SIGTERM을 사용하여 socat 프로세스를 중지하면 다음 메시지가 표시됩니다.

$ python3 demo.py < ttyFake
test
Traceback (most recent call last):
  File "~/serial-experiment/demo.py", line 3, in <module>
    for line in sys.stdin:
OSError: [Errno 5] Input/output error

나는 또한 이것을 시도했지만 운이 없었습니다.

$ echo -ne '\004' >> ttyFake.interface # send ^D

socat이 연결 해제 동작을 시뮬레이션하도록 하는 방법이 있습니까? 그것을 보내는 더 좋은 방법이 필요합니까 ^D?

^D하위 질문: 프로세스가 표준 입력에서 감지한 내용이 입력이 완료되었음을 결정하는지, 아니면 입력을 종료하기 위해 터미널 에뮬레이터에 보내는 것인지는 실제로 알 수 없습니다 .

답변1

테스트를 성공적으로 수행할 수 있는 해결 방법이 있습니다. 이것은 쉽게 문제의 일부일 수 있습니다. 따라서 "Cunningham의 법칙"을 이용하려고 할 수도 있습니다(Cunningham 자신은 이것과 아무 관련이 없는 것 같습니다).

$ mkdir solution
$ cd solution
$ cat > demo.py
import sys

for line in sys.stdin:
    print(line.strip())

print("DONE")
$ # make sure you ctrl+D at then end
$ mkfifo ttyConnector # DIFFERENT FROM QUESTION
$ socat -d -d pty,raw,echo=0,link=ttyFake pty,raw,echo=0,link=ttyFake.interface

새 터미널:

$ cd solution
$ cat > ttyConnector < ttyFake # DIFFERENT FROM QUESTION

새 터미널: (이렇게 부르자응용 단말기)

$ cd solution
$ python3 demo.py < ttyConnector # DIFFERENT FROM QUESTION

새 터미널:

$ cd solution
$ cat > ttyFake.interface
test
test
test
$ # make sure you ctrl+D at then end

(끝부분에 ctrlpython3 데모.py < ttyConnector+D가 있는지 확인하세요)

지금 봐응용 단말기

$ python3 demo.py < ttyConnector
test
test
test

pty로의 전송을 종료하더라도 fifo는 여전히 열려 있습니다.

하지만 socat 터미널로 돌아가서 Ctrl+C를 누르고 확인하세요.응용 단말기

$ python3 demo.py < ttyConnector
test
test
test
DONE

따라서 USB에서 FTDI를 분리하는 동작을 시뮬레이션하기 위해 fifo를 통해 모든 것을 전달하고 socat을 종료할 수 있는 것 같습니다. pty 쌍(FTDI 장치를 에뮬레이트하는 프로그램과 수신하는 프로그램)을 통해 두 개의 프로그램이 함께 연결되어 있습니다. 현재 이 해결 방법을 사용할 수 있는 이유는 수신기가 읽기를 위해 pty 쌍의 끝만 여는 반면 가짜 장치는 읽기 및 쓰기를 수행하고 테스트 자체에서는 쓰기를 수행하기 때문입니다.

            /--> P --> FIFO --> demo.py
FAKE DEVICE      T
            \<-- Y <-- TEST

양쪽 끝에서 단방향 통신만 필요하다면 socat을 건너뛰고 fifo만 사용합니다.

FAKE DEVICE --> FIFO --> demo.py

완전한 양방향 의사소통이 필요하다면 실질적인 솔루션이 필요하겠지만 아직은 모르겠습니다.

            /--> P -->\ 
FAKE DEVICE      T      demo.py
            \<-- Y <--/

Demo.py가 동일한 경로를 읽고 쓸 것으로 예상하는 경우 두 개의 fifo를 삽입하는 것이 그렇게 쉽지 않기 때문입니다.

그래서 저는 이 해결 방법 없이 PTY를 제대로 종료하기 위해 무엇을 해야 하는지 계속해서 알아보고 싶습니다.

관련 정보