y.nakamura
2025年1月18日 23時42分
久々にお世話になります。中村です。
Armadillo-IoTゲートウェイ A6E(以下"A6E")のRS-485インターフェースの
送受信切換え時間について質問です。
RS-485で接続してデータのやり取りを行う機器(以下"相手機器")の仕様で、
相手機器がリクエストを受け取った後に応答データを送信するまでの時間が
数マイクロ秒と規定されています。
相手機器の仕様書では"N±0.2[usec](typ)"(実際にはNは具体的な1桁の整数)の
ようにきっちり時間が記載されていますが、ここでは「数マイクロ秒」とします。
これにより、A6Eがリクエストコマンドを送信したあと、
この時間(数マイクロ秒)以内に受信できる状態にならなければなりません。
A6EのRS-485の送受信切換えは、この要求を満たすことができますか?
送受切換えの時間の「数マイクロ秒」というのは、A6Eが送信したリクエストの
最後のストップビットの終端エッジから、相手機器が送信する応答データの
スタートビットの開始エッジまでの時間です。
(図で示せばもっとわかりやすいのですが、文字だけでスミマセン)
次の過去記事と、そこに記載があるドライバのパッチ(リンク先)は見ました。
[Armadillo IoT A6Eを使用したRS-485シリアル通信の送受信間隔について]
https://armadillo.atmark-techno.com/forum/armadillo/19573
また最新のA6Eのカーネルソース(linux-at-a6-5.10.232-r0.tar)の
imx.cの該当箇所や周辺コードも読みました。
私の考えでは、数マイクロ秒という短い時間で送受切換えをするのは
無理なのではないかと思っています。
最新カーネルでは上の過去記事のパッチが適用されていないようですが、
それを適用しても、ドライバのプログラムの構造から、「数マイクロ秒」は
無理なのではないかと。。。
よろしくお願いいたします。
--
なかむら
コメント
y.nakamura
中村です。
溝渕さん、
いろいろ説明などをいただき、どうもありがとうございます。
> 上記に関しては、以下のパッチを適用することで改善方向には向かうと思います。
> https://wiki.linuxfoundation.org/realtime/preempt_rt_versions
またこれも、ありがとうございます。
顧客に対して「私は無理だと思う」だけでは説得力がないので、
アットマークテクノ様の見解が欲しく、今回の投稿になりました。
> ただ、先に述べましたように、私も数マイクロ秒以内での切換えを100%保証する事は厳しいかと思います。
お客様に「無理です」と連絡することにします。
今回の質問投稿よりも前にお客様に「A6Eに限らず、すべてのArmadilloで、
さらには、ArmadilloでなくてもLinuxを使っているボードマイコンで、
Armadilloと同様のハードウェア構成のものは全部無理だろう」、
「何か専用の装置(今回の要件を満たせるRS-485変換器など)を
使うしかないのではないか」、というような内容を伝えていました。
最初の私の投稿で
>> ... ドライバのプログラムの構造から、「数マイクロ秒」は
>> 無理なのではないかと。。。
と書きましたが、これは、LinuxがRTOSではないこともありますが、
それだけではなく、ドライバの
> 4. kernelでtx complete割り込み発生時にRS-485を受信状態に変更
の処理が重く(いろいろなことをやっているので)、
割り込み発生から送受切替までに時間がかかりすぎるということです。
ソースimx.cを見ると、割り込みハンドラのimx_uart_int()で、
割り込み処理に必要なすべてのレジスタを読み込んで、
いろいろ前処理をしてから割り込み要因の判定と分岐をしています。
今回のTXDC(送信完了/シフターが空になった)割り込みでは、
imx_uart_int()
=> imx_uart_transmit_buffer()
=> imx_uart_stop_tx()
という流れでimx_uart_stop_tx()の中で送受切替をしています。
この一連の処理だけで数マイクロ秒を消費してしまうような気がします。
(最近のマイコンの処理速度がどのくらいなのかよくわかってませんが)
他に有用な情報がなければ、本件はこれでクローズとしたいと思います。
どうもありがとうございました。
--
なかむら
y.nakamura
中村です。
それほど重要なことではないですが、先ほどの私の投稿で説明不足がありました。
> 今回のTXDC(送信完了/シフターが空になった)割り込みでは、
> imx_uart_int()
> => imx_uart_transmit_buffer()
> => imx_uart_stop_tx()
> という流れでimx_uart_stop_tx()の中で送受切替をしています。
この流れは、delay_rts_after_send=0で、かつ、
delay_rts_after_send=0のときの不具合パッチ
https://github.com/nxp-imx/linux-imx/commit/582e9a24fc139adabb1dc951620…
を当てた場合です。
--
なかむら
at_mizo
溝渕です。
結論としては変わりありませんが、CPUの処理能力について少しだけ、
Armadillo-IoT A6Eに搭載されているi.MX 6ULLのCPUであるCortex-A7のクロックは528MHzです。
RAMアクセスやキャッシュのヒット率にもよるので、当然このクロックの通りとはなりませんが、理想的には1命令当り時間は1/528(0.001893939)usです。
また、Transmitter complete割り込み(uartのshift registerの最後のbitを出力後に入る割り込み)発生後の処理は次のようになり、
Transmitter complete割り込み発生
=> imx_uart_int() //いくつかのレジスタ値のチェックしかしない
=> imx_uart_transmit_buffer() //開始直後のuart_circ_empty()で次に進む
=> imx_uart_stop_tx() //いくつかのレジスタ値の後A6EのRS-485を送受状態に切換え
多く見積もっても数100命令は無いかなという所感です。
なので、この処理だけを行うのであれば数usオーダーで十分かと感じています。
ただ、先述べましたように行儀の悪い(interrupt contextを長時間抜けない等)ドライバが無い事を全てに於て検証できておりませんし、割り込み禁止区間を行時間取るドライバが存在しない事も証明できない現状です。
以上より、どのような環境下に於ても100% 数usオーダーで処理を完了する事を保証できませんが、特定環境下では(たまたまですが)期待通り動作するという事も考えられなくはないかと思います。
私の感想を含む内容なので正確性に乏しい面もありますが、ご参考になりましたら幸いです。
at_mizo
2025年1月20日 9時35分
溝渕です。
> これにより、A6Eがリクエストコマンドを送信したあと、
> この時間(数マイクロ秒)以内に受信できる状態にならなければなりません。
>
> A6EのRS-485の送受信切換えは、この要求を満たすことができますか?
:(省略)
> 私の考えでは、数マイクロ秒という短い時間で送受切換えをするのは
> 無理なのではないかと思っています。
私も数マイクロ秒以内での切換えを100%保証する事は厳しいと思っています。
まず、LinuxはリアルタイムOS(時間制約を保証可能なOS)ではありません。
ただ、リアルタイムOSでない事実はありますが、RS-485の送受信切換えに関しては十分効率的に実装されている事も事実です。おおまかなシーケンスは次の通りです。
1. userlandから送信要求
2. kernelでRS-485を送信状態にしてdma送信要求
3. kernelでdma完了割り込みのcallbackでuartのtx complete割り込みを有効化
4. kernelでtx complete割り込み発生時にRS-485を受信状態に変更
と、kernel内で実行される状態遷移のきっかけとなるのはハードウェア割り込みであり、最もイベントに対する応答が早い実装になっています。
ただ、他の割り込み処理に時間がかかる事も考えられますし、割り込み禁止区間を作っているドライバもあります。恐らくそれら1つ1つを検証するのは困難かと思います。
上記に関しては、以下のパッチを適用することで改善方向には向かうと思います。
https://wiki.linuxfoundation.org/realtime/preempt_rt_versions
ただ、先に述べましたように、私も数マイクロ秒以内での切換えを100%保証する事は厳しいかと思います。