Armadilloフォーラム

A420/440の再起動時に起動せず停止状態になる可能性について

murakami_sec

2022年6月8日 17時30分

お世話になります。村上と申します。
設置先のA420/440で下記現象が出て原因を探しています。
どのような可能性が考えられるかご教授ください。

<現象>
A420/440の再起動(reboot)時に起動せず停止状態になることがあります。
似たような環境で398台中31台で現象が発生しています。

<補足>
USBケーブル、D-sub9pinを抜き差ししたらLEDの状態が変化し、rc.localが実行されたように見受けられました。
(こちらで製作したアプリが立ち上がったことが確認できたことからの推測です。アプリのログを確認したら起動直後でした)
uptimeコマンドで確認したら24Daysだったのでケーブル抜き差しによる再起動はしていないと考えます。
こちらで製作したアプリは起動直後だったことから、本現象に影響はないと考えます。

<条件>
JP1:オープン
JP2:オープン
D-sub9pin(CON3)で外部機器と通信(常時接続)
外部機器の電源はA420/440のUSBポートから電源のみ使用

<質問1>
A420/440で起動中(※1)、D-sub9pin(CON3)に、ごみデータ(※2)が入った場合、途中で停止状態(※3)になる可能性はありますか。
可能性がある場合、どのような条件でしょうか。

<質問2>
停止状態になった場合、再起動以外で復帰する可能性はありますか。
可能性がある場合、どのような条件でしょうか。

※1:ブートローダ、カーネル、ユーザランド
※2:9600bps(スタート8、パリティなし、ストップ1)でバイナリコード電文
※3:LED3、4どちらも点灯状態でrc.localが実行されていないように見受けられる(こちらで製作したアプリが動いていない)

以上、よろしくお願いいたします。

コメント

溝渕です。

以下、ソフトウェア構成に不明点があるので想像を含みます。

> D-sub9pin(CON3)で外部機器と通信(常時接続)

CON3は、外部機器との通信以外には用いておらず、「製作したアプリ」以外からは使われないという前提で以下記載します。

> <質問1>
> A420/440で起動中(※1)、D-sub9pin(CON3)に、ごみデータ(※2)が入った場合、途中で停止状態(※3)になる可能性はありますか。
> 可能性がある場合、どのような条件でしょうか。

まず、openしていないUARTは何もできないので、「製作したアプリ」は動作していると推測します。open後、入力されたデータに対して何かしらの動作を行うのは、以下2点のいずれかと思います。

- tty layer(制御端末にしている場合)
- 製作したアプリ

> <質問2>
> 停止状態になった場合、再起動以外で復帰する可能性はありますか。
> 可能性がある場合、どのような条件でしょうか。

これは、「停止状態」が具体的にどのような状態であるかを調査するのが良いかと思います。例えばプロセスが休止状態になっているのであれば復帰させれば良いですし、システムがハングアップしているのであればアプリまたはシステムの再起動が必要になると思います。

溝渕様

ご回答ありがとうございます。
返信が遅れてしまい、申し訳ございません。

> > D-sub9pin(CON3)で外部機器と通信(常時接続)
> CON3は、外部機器との通信以外には用いておらず、「製作したアプリ」以外からは使われないという前提で以下記載します。
こちらですが、現場で確認できた内容を以下に示します。
※たまたま、コネクタの抜差しで状態が変化し、Telnet接続が出来、確認がとれました。
・「uptime」コマンドで24日経過していたことを確認
・「ps」コマンドで「製作したアプリ」が起動していないことを確認

そのため、ご回答いただいた以下の推測が外れてしまいました。
> まず、openしていないUARTは何もできないので、「製作したアプリ」は動作していると推測します。
CON3は、標準のインターフェースとして使用されていて、起動時のログが出力されるので、こちらでOPENする前から使用されている認識です。
起動時のログ出力中に何か入力があることで停止する可能性がないでしょうか?

因みに、CON3のTXとRXをショートした状態で起動すると似たような現象が出ました。
何か関係はないでしょうか?

お手数をかけしますが、ご回答のほどよろしくお願いいたします。

溝渕です。

> CON3は、標準のインターフェースとして使用されていて、起動時のログが出力されるので、こちらでOPENする前から使用されている認識です。

CON3の用途は以下の認識で宜しいでしょうか?

- コンソールとして利用している
- 「製作したアプリ」からバイナリコード電文を送受信する

Linuxではttyデバイスを多重openすることが可能です。しかし、多重openする
ときっと意図した通りに動作しないと思います。特にデータ受信の場合、open
されたどのプロセスにデータが到達するかがわからなくなります。

なので、まずはコンソールとして利用しなくするのが良いかと思います。
# コンソールを無しにするとデバッグが困難になる可能性がある為、他の場所にコンソールを移動するのが良いかと思います。

溝渕様

ご回答ありがとうございます。

> CON3の用途は以下の認識で宜しいでしょうか?
> - コンソールとして利用している
→コンソールとして使用していません。
> - 「製作したアプリ」からバイナリコード電文を送受信する
その通りです。

CON3については、/etc/inittabで
#::respawn:/sbin/getty -L 115200 ttymxc1 vt102
上記のようにコメントアウトし、途中でコンソールとして使用しないようにしています。
その後、「製作したアプリ」が起動し、「製作したアプリ」内でCON3をオープンしています。

---
調査した結果、「製作したアプリ」など関係なく以下の環境で現象が出ることが確認できました。
・armadilloA440
・loader-armadillo4x0-v3.11.0.bin
(md5:bfa6873b442add42181c668195ed13b5)
・romfs-a440-2.04.img.gz
(md5:acad00e7e7dfe19d3accb5fce635a655)
・linux-a400-2.08.bin.gz
(md5:6b8947f9e186e7e9db1257fe9da2ec88)
・COM3にノイズ発生源あり(※添付参照)

プロアナでCON3を確認した結果(※添付参照)、COM3にゴミが入るとRxのFIFOオーバーランエラーが出てそこで停止しているようです。
Linux カーネル起動オプション(Hermit-At の setenv 機能)の設定で以下を行うと現象は出ませんでした。
hermit> setenv console=none(起動ログ出力先=なし)

話が変わってきましたが、ブートローダ?の脆弱性による現象ではないでしょうか?
また、本現象を回避するためには、Linux カーネル起動オプションで「起動ログ出力先」を「なし」に設定する以外の方法はないでしょうか?
(※CON9も別端末との通信で使用しています)

ファイル ファイルの説明
A440プロアナログ20220630.png

溝渕です。

すみません。先に1点確認させてください。

> > - コンソールとして利用している
> →コンソールとして使用していません。

コンソールとして使用していないのであれば、

> hermit> setenv console=none(起動ログ出力先=なし)

のように、"console=none"(コンソール無し)を指定すべきと思います。

> また、本現象を回避するためには、Linux カーネル起動オプションで「起動ログ出力先」を「なし」に設定する以外の方法はないでしょうか?

コンソールからログ出力がある状態で対向機器と通信しても問題無い構成でしょうか?

また、対向機器に対して起動ログを出力したい目的は何でしょうか?

溝渕様

> コンソールからログ出力がある状態で対向機器と通信しても問題無い構成でしょうか?
対向機器と通信するときには、コンソールからの出力をCON3に出さないようにしているので問題ないです。
対向機器は、コンソールから来た電文をゴミとして破棄します。

> また、対向機器に対して起動ログを出力したい目的は何でしょうか?

前回ご指摘いただいたように「コンソールを無しにするとデバッグが困難になる可能性がある為」です。
起動までに問題が発生した時にデバッグ出来るようにと考えていました。
起動してしまえば、Telenetなどで接続し状況を確認できるので起動後はコンソールからの出力をCON3に出さないようにしています。

> コンソールとして使用していないのであれば、
> > hermit> setenv console=none(起動ログ出力先=なし)
> のように、"console=none"(コンソール無し)を指定すべきと思います。

現時点で、上記ご指摘の方法が妥当だと思いますが、ゴミ入手でRxのFIFOオーバーランエラーが出て停止しているように見受けられたので、それはそれで問題があるのではないかと思いました。

以上、溝渕様の思われるご質問の回答になっていますでしょうか。

アットマークテクノの古賀です。

村上さん:
>>コンソールとして使用していないのであれば、
>>>hermit>setenv console=none(起動ログ出力先=なし)
>>のように、"console=none"(コンソール無し)を指定すべきと思います。
>
>現時点で、上記ご指摘の方法が妥当だと思いますが、ゴミ入手でRxのFIFOオーバーランエラーが出て停止しているように見受けられたので、それはそれで問題があるのではないかと思いました。

A420/440 のカーネルのソースツリーを見たところ、'Rx FIFO overrun' のログを出しているのは、
 /drivers/tty/serial/imx.c
で実装されている imx_int() ですね。この imx_int() は UART ドライバの割り込みハンドラですが、overrun エラーがステータスレジスタ(USR2)の ORE ビットで通知されている場合は、上記のログを出した後、ORE ビットに 1 を書いてクリアしています。以下の行です:

static irqreturn_t imx_int(int irq, void *dev_id)
{
    …(途中略)
	if (sts2 & USR2_ORE) {
 		dev_err(sport->port.dev, "Rx FIFO overrun\n");
		sport->port.icount.overrun++;
		writel(USR2_ORE, sport->port.membase + USR2);
	}
    …(途中略)
}

ためしに、このログ出力行(dev_err() の行)をコメントアウトしてビルドしたカーネルに入れ替えてみて頂けますか?
この行を削除したパッチも出ており、Armadillo-X1 の linux-4.9-at でも取り込んでいるようです:
 https://source.codeaurora.org/external/imx/linux-imx/commit/drivers/tty…
 https://github.com/atmark-techno/linux-4.9-at/blob/efe48ceee1ddd4149ab2…

パッチの説明には、次のように書かれています:

Background:
If an rx-fifo overflow occurs a dev_err message was called in interrupt
context. Since dev_err messages are written to console in a synchronous way
(unbuffered), and console may be a serial terminal, this leads to a
highly increased interrupt-latency (several milliseconds).
As a result of the high latency more rx-fifo overflows will happen, and
therefore a feedback loop of errors is created.

以上、もし参考になりましたら幸いです。

古賀様

詳細のご確認、ご回答ありがとうございます。

> ためしに、このログ出力行(dev_err() の行)をコメントアウトしてビルドしたカーネルに入れ替えてみて頂けますか?
了解いたしました。

> >>>hermit>setenv console=none(起動ログ出力先=なし)
> >>のように、"console=none"(コンソール無し)を指定すべきと思います。
急ぎでの対応が必要だったこともあり、現在は上記で対応するよう進めています。
もし、対応に問題があるようでしたらアドバイスをいただけると幸いです。

以上