串口重定向¶
串口目前在个人电脑主机上基本不存在了,但在一些小型设备特别是工业设备和工控机上还是能够看到这些接口。由于串口通信的方式和我们平时所使用的TCP/IP有很大差异,因此在调试和分析基于串口的通讯协议时所用的方法也会有所不同。
GOST在3.0.0-rc8之后的版本中增加了串口重定向或者也可以称做串口端口转发功能,可以将本地串口数据转发给TCP服务,或者将TCP服务的数据转发给本地串口,也可以将本地串口转发到远程主机的串口。利用串口转发可以实现两个功能:串口远程通讯和串口通讯数据监控。
虚拟串口
后面需要借助于虚拟串口让软件在不具备物理串口设备的主机上也可以进行串口通信。
Windows可以使用Null-modem emulator来创建虚拟串口。
Linux可以通过以下命令创建类似的虚拟串口:
串口远程通讯¶
串口的通讯是点对点的物理直连,没有网络的概念,因此需要设备在旁边时刻连着对端,这是物理空间上的一个局限性。通过串口转发可以做到像访问互联网服务一样来访问串口。这里有两种做法,一种是转发到TCP服务,另一种是转发到远程的串口设备。
转发到TCP服务¶
由于串口数据的传输方式和TCP协议类似,也可以看作是流式传输,因此可以将串口数据转发到一个TCP服务,这样就相当于将串口通信转换成了网络通讯。
转发到远程串口设备¶
如果一个软件需要通过串口与设备通信,正常的做法是在一台有串口的主机上安装软件,将设备通过串口线与此主机相连接,软件打开本地的串口设备,Windows下一般是COM口,例如COM1
,COM2
。Linux下一般是/dev/ttyS*
,例如/dev/ttyS0
,/dev/ttyS1
,如果是通过USB转串口,一般是/dev/ttyUSB0
。
但有些时候设备可能不在身边,或者设备无法移动,这个时候可以利用串口转发将设备所连接的主机上的串口转发到远程任意一台主机上,实现远程通讯。借助于虚拟串口工具,远程主机可以不具备物理串口。
假设设备所连接的主机A地址为192.168.1.1,主机A上的串口为COM1
。远程的一台主机B地址为192.168.1.2,主机B上已经通过虚拟串口工具虚拟出两个串口设备COM1
和COM2
,我们想要主机B上的软件通过虚拟串口COM2
与设备进行通信。
首先需要在主机A上开启中转服务:
然后在主机B上进行串口端口转发,将主机B上的COM1端口映射到主机A的COM1端口:
此时主机B上的软件通过COM2口所传输的数据会通过relay中转服务,转发到主机A的COM1口,实现了远程串口通信。
串口数据监控¶
对于TCP/IP网络通讯,可以借助于Wireshark,tcpdump等工具进行实时抓包来采集和分析数据,但是这些工具都不支持串口设备。因此对于串口设备一般都需要借助于专用的调试监控软件来抓取数据。
串口设备还有一个比较特殊的地方,一个端口同时只能被一个进程所占用,这就给抓取数据又增加了一定的难度。如果想抓取并监控软件与设备之间的正常通讯数据,常规手段就不可行了,目前仅找到Serial Port Monitor这一款软件可以做到对被占用的串口设备进行数据监控。
直接的监控不可行,可以通过串口转发来间接达到目的。同样需要借助于虚拟串口,假设主机A上有一个物理串口COM1
与设备连接,虚拟串口为COM3
和COM4
,此时可以让软件使用COM4端口,并将COM1转发到COM3,在转发的过程中就可以抓取数据进行监控。
services:
- name: service-0
addr: COM1
recorders:
- name: recorder-0
record: recorder.service.handler.serial
metadata:
direction: true
timestampFormat: '2006-01-02 15:04:05.000'
hexdump: true
handler:
type: serial
listener:
type: serial
forwarder:
nodes:
- name: target-0
addr: COM3
recorders:
- name: recorder-0
file:
path: 'C:\\serial.data'
这里在端口转发时使用记录器将通信数据记录到文件C:\serial.data
当中。最终的数据记录格式如下:
>2023-09-18 10:16:25.117
00000000 60 02 a0 01 70 02 b0 01 c0 01 c0 01 40 02 30 01 |`...p.......@.0.|
00000010 e0 00 30 01 50 02 60 01 40 01 30 01 10 02 f0 00 |..0.P.`.@.0.....|
00000020 20 01 60 01 b0 01 f0 00 10 01 f0 00 c0 01 a0 01 | .`.............|
00000030 40 02 b0 01 10 02 60 02 00 00 00 01 50 01 70 01 |@.....`.....P.p.|
00000040 a0 01 30 01 e0 00 e0 01 40 01 00 01 e0 00 c0 01 |..0.....@.......|
00000050 40 01 e0 00 f0 00 20 02 50 01 10 02 10 01 10 02 |@..... .P.......|
00000060 80 01 20 02 30 01 10 02 30 01 00 01 20 01 10 02 |.. .0...0... ...|
<2023-09-18 10:16:25.120
00000000 d0 00 d0 00 10 01 10 02 50 01 e0 00 00 01 d0 01 |........P.......|
00000010 f0 00 10 01 c0 01 40 02 80 01 00 01 20 |......@..... |
>
表示源端口发出的数据(COM1 > COM3),<
表示源端口接收到的数据(COM1 < COM3)。