シリアルポートパリティエラーを確認していますか?

シリアルポートパリティエラーを確認していますか?

いくつかのテストを実行したいデバイスがあります。私はそれが115200ボードに接続され、8つのデータビット、パリティなし、および1つのストップビットを持っていることを知っています。

私はこれらの設定を証明しようとしています。あるいは、少なくともこれらの設定が実際にデバイスで使用されている設定であることを証明するのに近づくことを試みています。デバイスは起動時に既知のデータを送信するため、テスト戦略は正しい設定で接続してデータを受信し、個々の設定を変更し、データが破損する可能性があることを予測することです。

ただし、pyserial または termios を使用して直接パリティまたはストップビット設定を変更すると、破損したデータは表示されません。 6ビットのデータサイズのみを変更すると、データが破損します。

パリティやストップビットエラーなどの問題を記録できる場所やログはありますか?パリティを記録するか、ビットエラーを停止するように調整できるtermiosを使用するいくつかの設定がありますか?

追加データ:実際のシリアルトラフィックはUSB-COM422-PLUS4ボードのFT4232Hを通過するため、テスト中のブラックボックスには/ dev / ttyUSB3と表示されます。

ベストアンサー1

ドライバが提供する内容に応じて、パリティエラーを検出し、正しいtermios設定でそれを計算することもできます。 ioctl TIOCGICOUNT(参照男4 tty_ioctl)はマニュアルページに文書化されていませんが、エラーカウンタを検索できます。 Pythonはioctlを提供していませんが、次のスクリプトはgetcounts.pyシステムに合わせて変更する必要がある低レベルのfcntl呼び出しを介してこれを行います。カーネルインクルードファイルに記載されている構造を使用してくださいserial.h。 (実際のシリアルデバイスのカウンタはにも表示されますが、/proc/tty/driver/serialUSBデバイスには表示されません。)

#!/usr/bin/python2
# https://unix.stackexchange.com/a/525261/119298
import sys, fcntl, array
# ioctl to get counters. see /usr/include/linux/serial.h
# struct serial_icounter_struct{
#  int cts, dsr, rng, dcd, rx, tx, frame, overrun, parity, brk,
#      buf_overrun, reserved[9]; }
def getcounts(filename):
    TIOCGICOUNT = 0x545D
    fd = open(filename)
    s = array.array('I',[0 for i in range(20)])
    rc = fcntl.ioctl(fd.fileno(),TIOCGICOUNT,s,True)
    if rc!=0:
        print "rc",rc
    names = "cts,dsr,rng,dcd,rx,tx,frame,overrun,parity,brk,bufo"
    cts,dsr,rng,dcd,rx,tx,frame,overrun,parity,brk,bufo = s[:11]
    for i,name in enumerate(names.split(",")):
        print name,s[i]
    fd.close()

getcounts(sys.argv[1])

たとえば、クロスオーバーケーブルを介して2つの物理シリアルポートを接続すると、次のスクリプトはパリティ検出設定を変更したときに3つの異なる結果を表示します。まず、2つのシリアルデバイスを同じに設定して、偶数パリティ(「not」-ignparと表示)を作成して検出します。-この関数はに書き込むtryために3回実行され、から結果を読み取るために使用され、最後にカウンタを印刷するために実行されます。hellottyS1xxdttyS0getcounts.py

#!/bin/bash
try()(
    xxd -l 16 /dev/ttyS0 &
    sleep 1
    for i in 1 2 3 ; do echo hello; done >/dev/ttyS1
    sleep 1
    getcounts.py /dev/ttyS0
)

stty -F /dev/ttyS0 9600 raw -echo clocal
stty -F /dev/ttyS1 9600 raw -echo clocal
stty -F /dev/ttyS0 parenb -ignpar inpck parodd
stty -F /dev/ttyS1 parenb -ignpar inpck parodd
try # should be ok
stty -F /dev/ttyS0 -parodd
try # should get parity errors, lots of null data
stty -F /dev/ttyS0 parmrk
try # should get parity errors, lots of ff 00 prefix to each data

最初の試みでは、データが正常でパリティカウントがゼロであることを示す必要があります(このデバイスを使い始めたばかりです)。

00000000: 6865 6c6c 6f0a 6865 6c6c 6f0a 6865 6c6c  hello.hello.hell
...
parity 0
...

次の試行の前に偶数パリティに変更してttyS0出力を取得します。

00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
parity 16

つまり、パリティエラーのあるすべての文字にはNULL文字があります。xxd16文字を読んで停止すると、実際のパリティエラーの数は16です。

最後の試みをする前に、私たちは尋ねます。表示データのパリティエラーです。これにより、カーネルは各無効なデータ文字の前に2バイトの0xffと0x00を配置し、次の結果を得ます。

00000000: ff00 68ff 0065 ff00 6cff 006c ff00 6fff  ..h..e..l..l..o.
parity 22

xxd終了時間が速いため、パリティ数は6ずつだけ増加します。

USBドライバの場合、上記のデータは同じでなければなりませんが、カウンタは何ら変わらない可能性があります。

おすすめ記事