pty를 생성하고 직렬 포트 /dev/ttyUSB0에 연결합니다.

pty를 생성하고 직렬 포트 /dev/ttyUSB0에 연결합니다.

질문:

직렬 인터페이스를 통해 두 개의 Linux 시스템이 연결되어 있습니다. 나는 그들 사이의 통신을 위해 ppp를 사용합니다(프로젝트 요구사항이기 때문에 이것을 해야 합니다). 통신 속도는 9600비트/초이다. 실시간으로 사용되는 대역폭(비트/초), 즉 시스템이 실행되는 동안의 대역폭을 측정해야 합니다. 처음에는 ifstat -btwTWS -i ppp0이 도구를 사용하도록 설계되었기 때문에 사용할 것이라고 생각했습니다 . 그러나 표시된 값은 9600비트/초를 훨씬 초과합니다. 약 12.09Kbits/s를 맴돌고 있습니다. 내가 물어봤지왜 이런 일이 발생합니까?, 응답은 압축으로 인한 것일 수 있다는 것입니다. 이것은 의미가 있습니다. 그러나 나에게 필요한 것은 압축 후와 압축 해제가 발생하기 전의 실제 비트/초입니다.

이 문제에 대한 나의 초기 해결책은 다음과 같습니다.

처음에는 데이터 속도를 표시할 수 있는 일종의 직렬 트래픽 스니퍼를 사용하고 싶었습니다. 여러 가지를 시도했지만 연결을 시도할 때마다 /dev/ttyUSB0리소스 사용 중 오류가 발생합니다. 이는 PPP가 장치를 인계받기 때문에 발생합니다.

이 문제를 해결하는 두 번째 방법은 다음과 같습니다.

의사 직렬 포트를 생성하여 실제 직렬 포트에 연결하고 싶습니다. 그런 다음 PPP가 가짜 직렬 포트를 인계받고 실제 직렬 포트의 트래픽을 스니핑합니다. 차트는 다음과 같습니다.

--------------------         -------------------------  
|                  |         |                       |
|      PPP         |         |        sniffer        |
|  -------------   |         |   ------------------  |              
|  | /dev/pty0 |---|---------|---|  /dev/ttyUSB0  |  |
|  -------------   |         |   ------------------  |
|                  |         |                       |
--------------------         -------------------------

내 이해는 socat이것이 가능하다는 것입니다. 이 글을 읽고 있지만 이 작업을 수행할 수 있는 옵션을 찾을 수 없습니다.

내 질문은 다음과 같습니다.

socat을 사용하여 의사 터미널을 만들고 실제 직렬 포트에 연결하는 방법은 무엇입니까? 가능합니까?

답변1

socat다음과 같은 간단한 명령을 사용할 수 있어야 합니다 .

socat pty,link=$HOME/myserial,rawer /dev/ttyUSB0,rawer 2>&1

~/myserial그러면 pty에 대한 심볼릭 링크가 생성되고 pty에 대한 모든 i/o가 직렬 포트로 복사되거나 직렬 포트에서 복사됩니다. 한 단계 더 나아가 -vI/O를 stderr에 복사하고 다음 -x형식의 헤더 라인을 사용하여 16진수로 인쇄하는 옵션을 추가할 수 있습니다 .

< 2019/01/12 18:16:36.528942  length=12 from=310 to=321

여기서 첫 번째 문자는 방향 <이고 >길이는 복사된 바이트 수입니다. 16진수를 사용하면 헤더 행이 원본 데이터와 혼동되지 않습니다. 다음은 이를 구문 분석할 수 있는 awk 스크립트입니다. 대략 10초마다 한 방향으로 초당 현재 바이트 수를 기록합니다.

socat -v -x pty,link=$HOME/myserial,rawer /dev/ttyUSB0,rawer 2>&1  |
awk '
 /^[><]/{ split($3,x,":"); tod = (x[1]*60+x[2])*60+x[3]; 
          split($4,x,"="); len = x[2]+0; 
          dir = $1=="<" ? "rx" : "tx";
          if(tod-lasttod[dir]>=10){
            printf "%s %f\n",dir,(len+tot[dir])/(tod-lasttod[dir])
            lasttod[dir] = tod
            tot[dir] = 0
          }else tot[dir] += len
}'

단순화를 위해 각 방향은 별도로 처리되며 시간을 자정으로 고정해야 합니다. 일반적인 출력은 다음과 같습니다.

tx 2.398754
rx 0.000425
tx 2.398772
rx 61.768501

관련 정보