k.sato
2024年8月20日 14時50分
佐藤と申します。
お世話になっております。
Armadillo Twin対応のArmadillo-640でuart2とuart5をRS-485通信として使用しています。
●uart2を使用してRS-485通信
https://armadillo.atmark-techno.com/index.php/forum/armadillo/19047
上記リンク先で質問してarmadillo-640-customize.dtsを下記のように修正し、
RS-485のDE/REピンをドライバで制御するようにしました。
/dts-v1/; /plugin/; #include <dt-bindings/gpio/gpio.h> #include "imx6ull-pinfunc.h" &uart2 { pinctrl-names = "default"; status = "okay"; fsl,uart-has-rtscts; rs485-rts-on-send; rts-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; linux,rs485-enabled-at-boot-time; }; &uart5 { pinctrl-names = "default"; status = "okay"; fsl,uart-has-rtscts; rs485-rts-on-send; rts-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; linux,rs485-enabled-at-boot-time; };
uart5をmodbus_tkのmodbus_rtu.RtuMaster
uart2をmodbus_rtu.RtuServerとして使用しています。
電源投入後は両方とも正常に通信できているのですが、
半日~1日エージングしているとuart2のDE/RE(GPIO3_IO24)がLに張り付き、
Armadilloの応答が受信出来なくなってしまいました。
TXピンはArmadilloへの要求に対して応答データをHi/Lowしています。
DE/REピンが動作途中でおかしくなることなんてあるのでしょうか?
何か原因を調査する方法がありましたら教えていただけませんか?
以上、よろしくお願い致します。
コメント
at_dominique.m…
k.sato
マルティネ様
佐藤です。
> > fe:
フレーミングエラーはわかるのですが、bo:
はどういうエラーなのでしょうか?
> bo は buffer overrun です。
> 受信に置いて、カーネルが文字を受け取ったがカーネル内のバッファーに入らないため捨てた文字の数です。
> アプリからの読み取り処理が間に合ってないみたいですね。それで完全に受信出来なることはないと思いますが、入力が化けてる場合は確認した方がいいかもしれません。
Armadilloへの要求間隔を空けて確認してみます。
またcat /var/log/messages
にてログを確認したところ下記のエラーが大量に出ていました。
Aug 23 10:10:27 armadillo kern.warn kernel: [ 1898.864877] imx-sdma 20ec000.dma-controller: All bds consumed,restart now.
これが原因だったりするのでしょうか?
以上、よろしくお願い致します。
at_dominique.m…
佐藤さん、
マルティネです。
> Aug 23 10:10:27 armadillo kern.warn kernel: [ 1898.864877] imx-sdma 20ec000.dma-controller: All bds consumed,restart now.
> これが原因だったりするのでしょうか?
このメッセージを検索したところ、負担が高い際に出力されることがあるそうです:
/* * re-enable HSTART_HE if all bds consumed at the last time, * that happens in high loading case which sdma_handle_channel_ * loop can't be handled in time while all bds run out in sdma * side, then sdma script clear HE and cause channel stop. */ if (count == desc->num_bd) { dev_warn(sdmac->sdma->dev, "All bds consumed,restart now.\n"); sdma_enable_channel(sdmac->sdma, sdmac->channel); }
私の理解では bd = buffer descriptor で、buffer が不足している場合に sdma (cpuの負担を減らすためのエンジン)が仕事できなくなるため自動的に無効化されて、ここでバッファーを処理したので再び有効しているだけです。
sdma が無効化なっている間に cpu で処理できているかどうかまでは確認してませんので、もしかしたらそのメッセージ直前にいくつかの文字を欠けてる可能性がありますが、そのメッセージが出力された後に受信が全くできなくなることはないはずです。
(こちらも、buffer overrun のエラーに似ていて、アプリケーションが /dev/ttymxcX のデーターを読むタイミングが遅いのが原因ではないかと思います)
佐藤さんのアプリケーションって python で rs485 のコマンドを読んで処理する仕組みだと認識していますが、切毒されている機器が Armadillo に一方的に大量のデーターを送信するものでしょうか?
Armadillo にコマンドを送った後に Armadillo が処理して返事すると思いますが、次のコマンドを送る前にまずは返事を待っていますでしょうか。
送信されているデーターをコントロールできない場合は試しにアプリケーションの処理を外して rs485 のデーターを読み取るだけようにすれば、再現できなくなると思いますがどうでしょうか。
よろしくお願いします。
k.sato
マルティネ様
佐藤です。
> 私の理解では bd = buffer descriptor で、buffer が不足している場合に sdma (cpuの負担を減らすためのエンジン)が仕事できなくなるため自動的に無効化されて、ここでバッファーを処理したので再び有効しているだけです。
> sdma が無効化なっている間に cpu で処理できているかどうかまでは確認してませんので、もしかしたらそのメッセージ直前にいくつかの文字を欠けてる可能性がありますが、そのメッセージが出力された後に受信が全くできなくなることはないはずです。
このエラーが出たからといって受信が出来なくなることはないのですね。
> (こちらも、buffer overrun のエラーに似ていて、アプリケーションが /dev/ttymxcX のデーターを読むタイミングが遅いのが原因ではないかと思います)
> 佐藤さんのアプリケーションって python で rs485 のコマンドを読んで処理する仕組みだと認識していますが、切毒されている機器が Armadillo に一方的に大量のデーターを送信するものでしょうか?
おっしゃる通りpythonで2口のrs485通信をしています。
uart5はマスタ動作していてArmadilloの要求に下層が応答します。
こちらは受信できなくなることはありません。
uart2はスレーブ動作をしていて上層からmodbusのレジスタ読み込み(0x03)コマンドが1秒間に11回あります。
Armadilloの応答データはそれなりのサイズがありますが要求コマンドは数バイトです。
> Armadillo にコマンドを送った後に Armadillo が処理して返事すると思いますが、次のコマンドを送る前にまずは返事を待っていますでしょうか。
接続機器は受信完了を待って要求コマンドを送信しています。
受信完了から次の送信までディレイを入れて確認中です。
やはり、通信のデータや頻度が高いのが問題でしょうか?
k.sato
マルティネ様
佐藤です。
週末にuart2の上位層からの送信間隔を50msから100msに伸ばしてエージングしましたが下記のエラーも発生せず、
通信不能になるということも起きなくなりました。
Aug 23 10:10:27 armadillo kern.warn kernel: [ 1898.864877] imx-sdma 20ec000.dma-controller: All bds consumed,restart now.
ここはやはり通信間隔を空けるしかないですか?
通信不能にならないのが一番よいのですが、
もし通信不能になった場合にエラーの検出方法や復旧方法はあるのでしょうか?
以上、よろしくお願い致します。
k.sato
佐藤です。
お世話になっております。
●RS485 を利用した Modbus RTU の通信ができなくなる
https://armadillo.atmark-techno.com/forum/armadillo/4289
●シリアル通信について
https://armadillo.atmark-techno.com/forum/armadillo/3520
Armadillo-IoT G3Lで上記のようにDMAを無効にすると安定するという件を見つけました。
同じようにArmadillo-640でもDMAを無効にして確認してみたいので
変更方法とArmadilloの書き換え方法を教えていただけませんか?
以上、よろしくお願い致します。
at_dominique.m…
佐藤さん
マルティネです
> Armadillo-IoT G3Lで上記のようにDMAを無効にすると安定するという件を見つけました。
そうですね、何かが変わるかもしれません。
> 同じようにArmadillo-640でもDMAを無効にして確認してみたいので
> 変更方法とArmadilloの書き換え方法を教えていただけませんか?
試してませんが armadillo-640-customize.dts に以下のようなブロックを追加していただければ uart に利用される sdma 全体が無効化されます:
&sdma { status = "broken"; };
どれかの uart の分だけの sdma を無効化したい場合は以下のようにもできると思いますが、確認してません
&uart2 { dmas = <0>; dma-names = <0>; };
よろしくお願いします
k.sato
at_dominique.m…
k.sato
マルティネ様
佐藤です。
> 確認してませんが、ls -l /sys/class/dma/dma0chan*/slave
の出力に無効化したシリアルコンソール(uart2 の場合は serial@21e8000)が表示されなくなるはずです(無効化しない場合に表示されるはずです)
●uart2 DMA有効 armadillo:~# ls -l /sys/class/dma/dma0chan*/slave lrwxrwxrwx 1 root root 0 Sep 5 14:38 /sys/class/dma/dma0chan0/slave -> ../../../2000000.spba-bus/2008000.spi lrwxrwxrwx 1 root root 0 Sep 5 14:38 /sys/class/dma/dma0chan1/slave -> ../../../2000000.spba-bus/2008000.spi lrwxrwxrwx 1 root root 0 Sep 5 14:38 /sys/class/dma/dma0chan2/slave -> ../../../../2100000.bus/21f4000.serial lrwxrwxrwx 1 root root 0 Sep 5 14:38 /sys/class/dma/dma0chan3/slave -> ../../../../2100000.bus/21f4000.serial lrwxrwxrwx 1 root root 0 Sep 5 14:38 /sys/class/dma/dma0chan4/slave -> ../../../../2100000.bus/21e8000.serial lrwxrwxrwx 1 root root 0 Sep 5 14:38 /sys/class/dma/dma0chan5/slave -> ../../../../2100000.bus/21e8000.serial
●uart2 DMA無効 armadillo:~$ ls -l /sys/class/dma/dma0chan*/slave lrwxrwxrwx 1 root root 0 Sep 5 14:39 /sys/class/dma/dma0chan0/slave -> ../../../2000000.spba-bus/2008000.spi lrwxrwxrwx 1 root root 0 Sep 5 14:39 /sys/class/dma/dma0chan1/slave -> ../../../2000000.spba-bus/2008000.spi lrwxrwxrwx 1 root root 0 Sep 5 14:39 /sys/class/dma/dma0chan2/slave -> ../../../../2100000.bus/21f4000.serial lrwxrwxrwx 1 root root 0 Sep 5 14:39 /sys/class/dma/dma0chan3/slave -> ../../../../2100000.bus/21f4000.serial
DMAを無効にしたときに21e8000.serial
が非表示になることを確認できました。
ありがとうございました。
k.sato
2024年8月21日 11時36分
佐藤と申します。
引き続き確認していて本日Armadilloからの応答がなくなった場合は
TXピンすらHi/Lowしていませんでした。
上記のようにコマンドを打ってみたのですが、
fe:
フレーミングエラーはわかるのですが、bo:
はどういうエラーなのでしょうか?以上、よろしくお願い致します。