在进行软件docker化的过程时,很大的一个阻碍就是软件与各种外围硬件设备的交互,网口通信的设备能够很容易地接入容器,但是串口设备则要复杂一些。本文讨论在windows和linux下docker容器使用串口的方法。

由于wsl2也在一直更新,不排除未来有可能直接支持wsl的情况

方案

docker run中提供了使用的本地设备资源的指令--device,但是依然有些限制,根据宿主与容器的情况,可以简单分为以下几种:

宿主Linux,容器为Linux容器

直接支持,在linux系统中,串口使用--device=/dev/ttyS1:/dev/ttyS2参数运行,即可直接在容器中访问串口1。

宿主Linux,容器为windows容器

没用过这个套路,太诡异了,本文不讨论这种情况。

宿主Windows,容器为Windows容器

按照官方的文档,需要使用CLASSID来做映射,官方给了一个示例,可以在windows容器中访问宿主机器的所有串口:

PS C:\> docker run --device=class/86E0D1E0-8089-11D0-9CE4-08003E301F73 mcr.microsoft.com/windows/servercore:ltsc2019

宿主Windows,容器为Linux容器

这里需要细分两种情况,分别对应WSL1与WSL2,其中WSL1可以直接访问本机的资源,文件也是可以直接访问的。

我机器上没有WSL1,也没有去尝试在WSL1基础上运行docker desktop并验证是否真实可用,有兴趣的读者请自行尝试。

WSL2就麻烦了,从官网文档的的比较来看,WSL2不支持访问宿主的串口设备,不过还是可以支持USB转串口设备。

Workaround

似乎在官方推出正式解决方案之前,这个方式无解了,但是我们可以将串口转成网口进行通信,从而实现docker变相访问串口。例如,对于硬件设备,可以通过RS232/485转以太网模块实现将串口通信,典型的模块有“有人串口服务器”系列的转换器。当然,也可以写一个小程序用来将串口接收到的数据转发到docker容器的端口。(如果host地址不同,那么使用类似socat命令可以实现转发)

注意,对于使用RTS之类的串口功能的通信,使用socket进行模拟可能不能模拟对应的访问控制。

参考