Armadilloフォーラム

Armadillo-420(Linux3.14)でUSBシリアル通信不正

sirakawa

2025年7月24日 20時38分

==========
製品型番:Armadillo-420
Debian/ABOSバージョン:atmark-dist v1.55.1
カーネルバージョン:Linux 3.14.36-at13
3G/LTE モジュール情報 (Debianのみ):
その他:
==========
いつもお世話になっております。

【構成】
 [Armadillo-420] - [USBハブ] - [対向機]
 このような構成でUSBシリアル通信をしています。
 動作確認用に、同じサイズ(3600バイト)・同じデータ(連番データ)を対向機から毎秒受信しています。
 対向機に対してデータ送信指示を送って、データ受信を行っています。
 Armadillo-420側ではデバイスファイルをopen/send/read/closeするプログラムを使用しています。

【通信設定】 ※仕様で決まっているため、変更不可。
 ボーレート:921600
 パリティ:なし
 フロー制御:なし

【事象】
以下の事象が起きています。
(a)受信サイズが想定値未満になるときがある。サイズは不定。データの末尾が欠落するのではなく、中盤のデータが欠落する。
(b)受信データの間に0x00が間に挟まるときがある。挟まる場所は不定。

今のところ、(a)(b)は同時に発生します。発生時間も不定です。
  期待値:・・・,0xa1,0xa2,0xa3,0xa4,・・・,0xd1,0xd2,0xd3,・・・,0xf6,0xf7,0xf8,・・・
  受信値:・・・,0xa1,0xa2,0x00,0xa3,0xa4,・・・,0xd1,0xf7,0xf8,・・・
  →事象(a):0xd2~0xf6が欠落している
   事象(b):0xa2の後に想定外の0x00が入っている

【お聞きしたい内容】
(a)について
 フロー制御を使用していないUSBシリアル通信であるため、データの欠落は回避しようがないでしょうか?

(b)について
 (a)はまだ理解できるのですが、こちらが理解できません。
 どのような時にこれが起こり得るか、心当たりのある方いらっしゃいませんでしょうか?

事象について、問題箇所の切り分け(アプリケーション/カーネル/対向機/その他)ができておりません。
例えばreadでの読み出しサイズが1200のとき、0x00も含めて1200バイトとなっているため、現状はアプリケーションが原因ではないという想定をしています。また、対向機の送信データがどうなっているかを確認しようとしています。
このような状況で申し訳ございませんが、ご回答いただけますと幸いです。よろしくお願いいたします。
解析の方法の参考情報などでも構いません。

コメント

溝渕です。

> (a)について
>  フロー制御を使用していないUSBシリアル通信であるため、データの欠落は回避しようがないでしょうか?

そうですね。一般論ですが、フロー制御はこのようなデータ欠落を防止する為に存在します。フロー制御無効の場合は(特に非リアルタイムOSであるLinuxの場合は)データが欠落する可能性があります。

データの欠落を防止するには、フロー制御を有効にすうか、ユーザーランドで(zmodemのような)プロトコル実装をするのが良いかと思います。

> (b)について
>  (a)はまだ理解できるのですが、こちらが理解できません。
>  どのような時にこれが起こり得るか、心当たりのある方いらっしゃいませんでしょうか?

心当たりはありませんが、切り分け方法だけ。

以下2つが考えられます。
- 実際に0x00が送信されている(だからArmadilloが受信する)
- 実際には0x00が送信されていない(だけどArmadilloが受信する)

>  [Armadillo-420] - [USBハブ] - [対向機]

Armadillo-420-USBハブ間であれば、USBアナライザ、
USBハブ-対向機間であれば、プロトコルアナライザやオシロスコープ
で確認可能かと思います。

他には、Armadillo-420のtty設定で充填文字(sttyコマンドでいうところのofill)が設定されていないか等、プログラムの確認をする事も有益かと思います。

投稿の期間が空いてしまいましたが、継続調査しています。

>USBハブ-対向機間であれば、プロトコルアナライザやオシロスコープ

オシロスコープで対向機の送信データを連続で保存し、
Armadillo-420で事象が発生した瞬間の波形を確認したところ
波形は期待通りとなっていました。
これにより、対向機は正常データを送信していると判断しました。

>  [Armadillo-420] - [USBハブ] - [対向機]

[Armadillo-420]を別の機器(小型パソコン。OSはRHEL 7.9)に置き換えたところ
事象は発生しませんでした。

以上2点から、
- [USBハブ] - [対向機]  までは正常であり、
[Armadillo-420]での受信後にアプリケーションがreadでデータを取得するまでの
どこか(ハードウェア or カーネル)で事象が発生していると推測しています。

この調査をするにあたり、該当のドライバソースにprintkでログを追加し
解析していくイメージなのですが、他に良い解析方法などございますでしょうか?

溝渕です。

> [Armadillo-420]での受信後にアプリケーションがreadでデータを取得するまでの
> どこか(ハードウェア or カーネル)で事象が発生していると推測しています。
>
>
> この調査をするにあたり、該当のドライバソースにprintkでログを追加し
> 解析していくイメージなのですが、他に良い解析方法などございますでしょうか?

[armadillo]# cat /proc/tty/driver/[ドライバ名]

の出力に、"oe"の項目があれば、fifo overrunのエラーが発生したと判断できます。この場合は受信が間に合っていない事が確定する為、

- 受信割り込みが(他の割り込み等によって)ブロックされている
- USB Serialの受信処理に時間がかかり過ぎている(作りが悪い)

等を確認するのが良いかなと思います。

また、USB Serialのdriverで、tty bufferに受信文字をpushしている箇所で、"0x00"を受けていないか確認するのも有益かと思います。

アイディアだけですみません...。

溝渕様

ご返信ありがとうございます。
我々に無いアイディアをいただけるため、大変助かります!
まずは/procの方から確認してみます。

溝渕です。

> エラー発生時は表示されるのでしょうか?

USBシリアルドライバが適切にエラーカウンタをインクリメントする場合は表示されるかと思います。

溝渕です。

お使いのUSBシリアルのチップ(またはアタッチされるドライバ)を教えていただく事は可能ですか?

> お使いのUSBシリアルのチップ(またはアタッチされるドライバ)を教えていただく事は可能ですか?
以下の製品を使用しています。
https://akizukidenshi.com/catalog/g/g105840/

FTDI USB Serial Device converter として認識されています。
[root@armadillo420-0 (ttymxc1) ~]# dmesg | grep ttyUSB
usb 2-1.4.4.4: FTDI USB Serial Device converter now attached to ttyUSB0
usb 2-1.4.4.3: FTDI USB Serial Device converter now attached to ttyUSB1

溝渕です。

> [root@armadillo420-0 (ttymxc1) ~]# dmesg | grep ttyUSB
> usb 2-1.4.4.4: FTDI USB Serial Device converter now attached to ttyUSB0
> usb 2-1.4.4.3: FTDI USB Serial Device converter now attached to ttyUSB1

2つのUSB Serialが接続されているようですが、

[Armadillo-420] --- [USB Hub] --- [TTL-232R-3V3] --- [対向機]
                           '----- [TTL-232R-3V3] --- [対向機]

のような構成でしょうか?

USB Hub無しで、1つのUSB Serialだけの構成であれば、正常に通信できたりしますか?

溝渕です。

> USBシリアルドライバが適切にエラーカウンタをインクリメントする場合は表示されるかと思います。

エラーカウンタは適切にインクリメントされているように見えます。

drivers/usb/serial/ftdi_sio.c:
static int ftdi_process_packet(struct usb_serial_port *port,
		struct ftdi_private *priv, char *packet, int len)
{
 :snip
	if (packet[1] & FTDI_RS_ERR_MASK) {
		/* Break takes precedence over parity, which takes precedence
		 * over framing errors */
		if (packet[1] & FTDI_RS_BI) {
			flag = TTY_BREAK;
			port->icount.brk++;
			usb_serial_handle_break(port);
		} else if (packet[1] & FTDI_RS_PE) {
			flag = TTY_PARITY;
			port->icount.parity++;
		} else if (packet[1] & FTDI_RS_FE) {
			flag = TTY_FRAME;
			port->icount.frame++;
		}
		/* Overrun is special, not associated with a char */
		if (packet[1] & FTDI_RS_OE) {
			port->icount.overrun++;
			tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
		}
	}

mainlineに入っているftdi_sioのbug fixのパッチをいくつかbackportしてみたので、適用して動かしてみていただけますか。添付のpatches.tar.gzにまとめて入れています。
# ビルドのみ確認済み/動作未確認 である点をご了承ください

ファイル ファイルの説明
patches.tar.gz

> 2つのUSB Serialが接続されているようですが、
混乱を招いてしまい申し訳ございません、
複数接続している構成ではあるのですが、問題が起きているのはttyUSB1の方です。

> USB Hub無しで、1つのUSB Serialだけの構成であれば、正常に通信できたりしますか?
少々特殊な構造になっていまして、こちらはまだトライできておりません。
お客様に確認したいと思います。

> > USBシリアルドライバが適切にエラーカウンタをインクリメントする場合は表示されるかと思います。
> エラーカウンタは適切にインクリメントされているように見えます。
エラーが発生した場合は表示されるということですね。
ご確認ありがとうございます。

> mainlineに入っているftdi_sioのbug fixのパッチをいくつかbackportしてみたので、適用して動かしてみていただけますか。添付のpatches.tar.gzにまとめて入れています。
> # ビルドのみ確認済み/動作未確認 である点をご了承ください
助かります。ありがとうございます。
Linux4.14のドライバを取り込むトライをするかを悩んでいたところでした。