Armadilloフォーラム

RS485の半二重シリアル通信について

yasushi.sekine

2020年5月13日 18時03分

お世話になっております。

ある機器を制御するプログラム(RS485通信)をArmadillo+自社製拡張ボード上で作成しています。
Armadillo→機器へのデータ送信、DE/RE端子の切替に時間がかかっているようで、データ送信後の機器からの受信データの先頭数~数十バイトがうまく取れない現象が発生しています。
機器側は要求送信後、数msecで応答を返す仕様なので、プログラム側のデータ送信処理時間がかかっていることが影響してDE/RE端子が切り替わらず、データが欠落しているのではないかと考えていますが、なぜ時間がかかるのかまで原因の特定までができていません。
何かわかること、回避方法等がありましたら、ご教授いただけると助かります。

■機器との通信仕様(1例)
 ・RS-485 2 線式伝送(半二重)
 ・伝送速度:9600bps
 ・パリティ:Even
 ・データ:8
 ・ストップビット:2 bit
 ・フロー制御:なし

■環境
 ・Armadillo-X1(linux-4.9-x1-at12)
 ・Debian 9
 ・CON8に自社製拡張IFボードを接続(以下に一部抜粋)
  RXD CON8-72pin
  RE CON8-76pin
  DE CON8-77pin
  TXD CON8-73pin
 ・言語はpython3.5(pyserial 3.4 RS485モード使用)
 ・拡張IFのデバイスツリーを修正しビルド

■大まかなプログラムの流れ
 ①DE、RE端子(GPIO)切替(High:受信不可、送信可)
 ②プログラム→機器へ要求を送信
  ※送信データは8バイト
 ③DE、RE端子(GPIO)切替(Low:受信可、送信可)
 ④機器→プログラムへ情報を送信(プログラム上で受信)
 ※簡易テスト用プログラムも添付します

■確認
 1.オシロで波形を確認
  ・上記流れの①と同時に②開始
  ・②の送信波形:10 msec
  ・①~③までの端子切替波形(High→Lowまで):20 msec
  ・その後機器からのデータを受信
   → ※②の10msec直後にDE、RE端子がLowになってほしい
 2.DE,RE端子のHigh/Low切替を単体で試してみたところ250μsec前後で切替できている
 3.送信(write)処理とDE、RE端子制御を絡めるとGPIOの切替に20msecかかる
 4.pyserialのライブラリを確認したところwrite後のflush( termios.tcdrain(fd))が遅い:十数msec
 5.Armadillo-X1からRs485-USB変換アダプタで試してみると端子の影響は受けないのか送受信問題なし

■補足
 念のため、以下等も確認済み
 https://armadillo.atmark-techno.com/forum/armadillo/3892
 https://armadillo.atmark-techno.com/forum/armadillo/3520#comment-6333

ファイル ファイルの説明
test_rs485.txt
コメント

佐藤です。

DE/REの制御をgpio sysfs経由で行っているためと考えられます。
arch/arm/boot/dts/armadillo_x1l.dts の uart2 の部分などを参考に
i.MX uartドライバに実装されたRS485機能を利用するようにする必要があります。

また、上記以外に下記フォーラムで紹介されているパッチも適用必要かもしれません。
https://armadillo.atmark-techno.com/forum/armadillo/4289

お世話になります。

ご返信ありがとうございます。
デバイスツリーを記載して試してみましたが、結果は変わらずでした。
※パッチも適用済み

デバイスツリー適用において色々と他サイトを参考にしていますが、理解が足りていない部分がありそうな気がしています。
つきましては、RS485機能を利用するようなデバイスツリーの書き方は正しいでしょうか?(以下)
何か不足の点等ありましたら、ご指摘いただけると助かります。
-------
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
assigned-clocks = <&clks IMX7D_UART2_ROOT_SRC>, <&clks IMX7D_UART2_ROOT_DIV>;
assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
assigned-clock-rates = <0>, <80000000>;

+ rs485-enabled-at-boot-time;
+ fsl,rs485-tx-gate-type = "gpio";
+ fsl,rs485-tx-gate-gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+ fsl,rs485-rx-gate-type = "gpio";
+ fsl,rs485-rx-gate-gpio = <&gpio3 4 GPIO_ACTIVE_LOW>;

status = "okay";
};
---------------

佐藤です。

以下のように修正するといかがでしょうか。
※こちらではビルドできることは確認しておりますが、動作確認はしておりません。
-------
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
assigned-clocks = <&clks IMX7D_UART2_ROOT_SRC>, <&clks IMX7D_UART2_ROOT_DIV>;
assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
assigned-clock-rates = <0>, <80000000>;

+ rs485-rts-active-high;
+ rs485-enabled-at-boot-time;
+ rts-gpio = <&gpio3 5 0>;
+ fsl,uart-has-rtscts;

status = "okay";
};

+ &gpio3 {
+ rs485_re {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "RS485_RE";
+ };
};
---------------

お世話になっております。

返信遅れましたが、欠落なく正常にデータを受信できるようになりました。
ありがとうございます。

正常にデータを受できたものの、参考までに1点確認させてください。
オシロで送受信データの波形を確認していたところ、DE端子がHigh状態のときにデータ送信していることを確認していますが
TXDだけでなくRXDにも同様のデータが流れているような波形を観測しています。(添付:オシロ確認.png参照)
プログラム的には問題ないので、おそらくドライバ側でよしなに(DE端子HighのときはRXDの受信をしても破棄など)してくれているのかと
考えていますが、念のため問題なさそうかご教授いただけると非常に助かります。

※ハード側に疎い部分がありますので、的が外れた質問でしたらご容赦ください
※オシロ確認.png説明
 CH1(オレンジ色):DE波形
 CH2(水色):TXD波形
 CH3(紫色):RXD波形

ファイル ファイルの説明
オシロ確認.png

溝渕です。

> プログラム的には問題ないので、おそらくドライバ側でよしなに(DE端子HighのときはRXDの受信をしても破棄など)してくれているのかと
> 考えていますが、念のため問題なさそうかご教授いただけると非常に助かります。

問題ありません。
# 半二重通信なので、TXDとRXDは同じ信号になります。

データ送信中(DE端子Highのとき)は、i.MX 7DのUARTコアの機能でRXDの受信を
拒否しています。RX FIFOにデータが入ることはありません。

お世話になっております。

素早いご対応ありがとうございます。
問題ないこと承知致しました。
また、補足についてもありがとうございました。

こちらクローズとさせていただきます。