docker container でシリアルポートからのデータを扱いたい
Jetson NanoでUSBでu-blox 受信機を接続して、docker container でデータを読むことができました。
そのときのメモです。多分、Jetson Nanoや u-blox は関係なく、一般的な初歩的なお話だと思います。(^^;)
復習も兼ねて「くどく」書いています。。。
ポイントは、Docker のマニュアルにもありますが、ホスト側のシリアリポートをそのまま仮想環境にマッピングするには、一言、docker run の引数に書くだけでOKです。
docker run --device=<ホストOSのdevice>:仮想環境のdevice>
とするだけです。実際は、Docker-docs-ja で
等を読むと、権限や通信帯域の設定など、細かい話もあるにはあります。が、今回はホストOSと同じ設定(どちらもubuntu18.04だし)なのでdon't care でOKでした。
動作確認
以下、Jetson Nanoでu-blox M8TをUSBで接続し、最後にdocker run
で入力を読めることを確認したときのメモです。
シリアル通信するデバイスの動作確認
デバイスはu-blox M8Tを使いました。(だから何だ。。。)
$lsusb
Bus 001 Device 004: ID 1546:01a8 U-Blox AG
Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$dmesg
...
[1442054.399797] tegra-xusb-padctl 7009f000.xusb_padctl: power on UTMI pads 1
[1442054.403431] tegra-xusb 70090000.xusb: Firmware timestamp: 2019-10-17 15:58:59 UTC, Version: 50.25 release
[1442054.404047] tegra-pmc: PMC tegra_pmc_utmi_phy_disable_sleepwalk : port 0
[1442054.404242] tegra-pmc: PMC tegra_pmc_utmi_phy_disable_sleepwalk : port 1
[1442054.404427] tegra-pmc: PMC tegra_pmc_utmi_phy_disable_sleepwalk : port 2
[1442054.405876] tegra-xusb 70090000.xusb: exiting ELPG done
[1442054.409069] usb usb2: usb_suspend_both: status 0
[1442054.750106] usb 1-2.4: new full-speed USB device number 4 using tegra-xusb
[1442054.773772] usb 1-2.4: New USB device found, idVendor=1546, idProduct=01a8
[1442054.773846] usb 1-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[1442054.773896] usb 1-2.4: Product: u-blox GNSS receiver
[1442054.773944] usb 1-2.4: Manufacturer: u-blox AG - www.u-blox.com
[1442054.864251] cdc_acm 1-2.4:1.0: ttyACM0: USB ACM device
[1442054.864676] usbcore: registered new interface driver cdc_acm
[1442054.864679] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
$ ls -lth /dev/ttyACM*
crw-rw---- 1 root dialout 166, 0 10月 19 17:08 /dev/ttyACM0
u-blox 受信機をUSBポートにさしました。
$ sudo usermod -a -G dialout $USER
$ screen /dev/ttyACM0 115200
screenはctrl+a d で終了します。
docker 素材の用意
次に、シリアルポートからデータを読む python スクリプトを用意します。pyserialを使います。
#!/usr/bin/env python3
import sys
import serial
port = sys.argv[1]
with serial.Serial(port, 115200) as ser:
while True:
data =ser.read(1024)
print(data)
python3 serial_read.py /dev/ttyACM0
で動作確認をした後、Dockerfile を作成します。
FROM ubuntu:18.04
# Install python and pip
RUN apt-get update -y && \
apt-get install -y -qq --no-install-recommends \
python3 \
python3-serial \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENV PATH /usr/local/bin/:$PATH
# the port number the container should expose
COPY serial_read.py /usr/local/bin
RUN chmod +x /usr/local/bin/serial_read.py
ENTRYPOINT [ "serial_read.py" ]
動作確認
できたら、build して動かしてみます。ここでは、仮想環境でのシリアルポートを /dev/myserialport としました。
$ docker build -t test/serial .
Successfully tagged test/serial:latest
$ docker run --device=/dev/ttyACM0:/dev/myserialport --rm -it test/serial /dev/myserialport
b'$GNRMC,093210.00,V,,,,,,,191020,,,N*61\r\n$GNVTG,,,,,,,,,N*2E\r\n$GNGGA,093210.00,,,,,0,00,99.99,,,,,,*71\r\n$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E\r\n$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E\r\n$GPGSV,2,1,06,04,,,13,05,,,12,20,,,21,24,,,11*7B\r\n$GPGSV,2,2,06,26,,,09,29,,,21*7A\r\n$GLGSV,1,1,00*65\r\n$GNGLL,,,,,093210.00,V,N*5D\r\n$GNZDA,093210.00,19,10,2020,00,00*78\r\n$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E\r\n$GNTXT,01,01,02,HW UBX-M8030 00080000*60\r\n$GNTXT,01,01,02,EXT CORE 3.01 (111141)*39\r\n$GNTXT,01,01,02,ROM BASE 2.01 (75331)*19\r\n$GNTXT,01,01,02,FWVER=TIM 1.10*50\r\n$GNTXT,01,01,02,PROTVER=22.00*18\r\n$GNTXT,01,01,02,MOD=NEO-M8T-0*7D\r\n$GNTXT,01,01,02,FIS=0xEF4015 (100111)*58\r\n$GNTXT,01,01,02,GPS;GLO;GAL;BDS*77\r\n$GNTXT,01,01,02,SBAS;IMES;QZSS*49\r\n$GNTXT,01,01,02,GNSS OTP=GPS;GLO*37\r\n$GNTXT,01,01,02,LLC=FFFFFFFF-FFFFFFED-FFFFFFFF-FFFFFFAE-FFFFFF69*27\r\n$GNTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*3E\r\n$GNTXT,01,01,02,ANTSTATUS=OK*25\r\n$GNTXT,01,01,02,PF=3FA*4C\r\n$GNRMC,093211.00,V,,,,,,,191020,,,N*60\r\n$GNVTG,,,,,,,,,N*2E\r\n$'
無事に動いたのでよかった。(^^)/
まとめ
とりあえず、docker でシリアルポートを扱うことはできた。リソースの取り扱いにはオプションがあるので、将来的にはそれらを使うことになるかもしれないので、そのときはそのとき。
(2020/10/19)