スパイス  組み込み制御装置の受注製作

ライブラリの導入
平成27年 4月29日

 PIC32の周辺機能(USART)を活用する(その6) 送受信での待ち時間の検討
 当面の目標仕様が固まったところで、実際のプログラムが必要ですが、こちらはまだ手付かずです。送信側と受信側を書き上げて動作の確認ができるまで数日はかかるでしょう。
 その間に、通信時間の大半を占める待ち時間の検討を進めます。最初の実験段階では、充分すぎるほどの待ち時間を与えて、まずは正しく動作することを確認します。その次には、実用化を前提に、適度なマージンを確保した状態でどの程度まで通信速度を上げることが出来そうかを検討します。その検討の原案となる基本的な待ち時間の決め方について先に考えてみます。

 通信のタイミング図は以前に示したのですが、再度同じものを示します。
マスタ側    [Dn]|<------ T1 ---------->[D1]<---- T2 ---->[D2]<--   -->[Dn]|<----- T5 ------->    
         --------------------------------------------------------------------------------------------------
スレーブ側  [Dn]|                                                         |<-T3->|  [R1]<-- T4 -->[R2]
これらの待ち時間T1〜T5を何を基準に決めるべきかについて考えてみます。
 まずは、マスタからの送信完了後次の送信開始までの待ち時間T2です。
この待ち時間は、スレーブ側のCPUがデータを受信して内部の受信バッファに転送するまでの処理を待っています。これらの処理は全て割り込み処理関数内で行えますので、基本的にはスレーブ側のCPUが現在の処理を中断してUSARTの割り込み処理関数の処理を終える最悪のケースを想定すれば良いことになります。
 最初の検討ですので少し細かく考えてみます。割り込み処理に関連する項目としては、下記が上げられます。
(もっと厳密な検討が必要な状況もあり得ますが、非常に稀なケースなので今回は除外します)
  1. メイン側での最大割り込み禁止時間
  2. 自身の割り込みより優先度の高い割り込み処理の中で割り込みが重なる可能性がある割り込み処理の総合計時間
  3. 自身の割り込みと同じ優先度の割り込み処理(副優先度は低くても考慮する)で処理時間が非常に長くかかる割り込み処理の処理時間
  4. 自身の割り込み処理時間

 まず、割り込みコントローラで複数の主割り込み優先度を使用する場合は、1+2+4 か 2+3+4 のどちらか長い方の処理時間以上が必要です。
主割り込み優先度を一つの値に統一してある場合は主割り込み優先度を副割り込み優先度と読み替えれば、ほぼ同じ結果になります。
ワーストケースでの動作順序はこのようになります。  もう一つは下記の状況です。  一般的にはスレーブ側CPUはIO処理のみを受け持つことが多いので、それ程時間の長くかかる割り込み処理や多くの割り込み要因を使用することは無く、それ程長い待ち時間は必要ないと思われます。
 逆にUSBやイーサネットのようにそれなりに時間のかかる割り込み処理を扱う場合は、これらの割り込み毎の処理時間を実測しておく必要があります。中には当初思った以上に長い処理時間がかかるものがあります。そして、割り込みの優先度の決定には十分な注意が必要です。

 これらの処理時間の中で最も計測が面倒なのはメイン側での割り込み禁止時間です。メイン側には各所にこのような箇所があります。それらの中で最も割り込み禁止時間の長いのは何処で何us割り込み禁止しているかを確認するのはかなり面倒です。その計測用に専用のマクロを使って測ることになるでしょう。しつこいようですが僅か数行の処理でも関数呼び出しが一個でもあれば、その処理時間を予測することは簡単ではありません。そのソフトを書いた担当プログラマといえども、その処理時間をある程度(正確なでは無く)妥当な範囲で予測することすら困難です。
 では、実際にはT2の設定値をどのように決めればいいか?
全ての実測値が揃うまでは、十二分にマージンをとった値を設定しておきます。その後、各測定値の合計の2倍程度の値を設定しておけば問題は無いでしょう。もし、一つでも実測できない項目があれば、その分だけ余分にマージンを見ておきます。組み込み装置では割り込みに対する応答性は最重要の項目です。一度通信エラーが起きるとそのリカバリーには大きな代償を伴います。まずは、遅くとも確実に動作する設定で動作させることが重要です。僅かばかりの性能向上のために通信エラーを頻発させるのは馬鹿げています。
 これでやっと最初のT2が決まりました。


 では次はT1の決め方を考えます。
T1の目的は送信データの先頭を示すために、二番目以降の送信データとは区別できるようにすることです。
つまり、二番目以降のデータがT2だけ待ち時間をとって送信した場合の最悪条件よりも確実に長い待ち時間である必要があります。
これをもう少し細かく見ていきます。最初のデータを送信終了した後でT2の待ち時間が経過するのを待っている状態では、CPUはこの待ち時間をポーリングで待っています。当然、専用のタイマと割り込み処理で行うことも出来ますが、タイマの数は限られているので無駄遣いしたくはないのが普通です。この場合、ポーリングの周期はマスタ側の処理ループが一回りする時間に依存します。下記に簡単なタイミング図を示します。この図のように待ち時間T2はポーリング周期分の誤差を伴います。この誤差を加味してもスレーブ側で正しく送信データの先頭であると判断できるだけの時間的な余裕が必要です。
   T1 > T2 + (マスタ側CPUのポーリング周期) + 検出に掛かる誤差(スレーブ側での割り込み受付までの時間的遅れ) + マージン
マスタ側      [D1]<---------T2 --------><誤差>[D2]
         --------------------------------------------------------------------------------------------------
ポーリング周期        |    |     |      |      |
 実際には、かなりの時間的余裕をもって決めることになります。プログラムは作られた後も何度も修正が行われます。それを加味しても十分なマージンがないと、後からプログラムを変更する担当者には、このような事情までは伝わっていないでしょう。修正したら思わぬ通信異常に苦しめられることになります。ブロック転送を採用することで従来の数倍以上の通信能力を得ることが出来ます。あまりケチケチしないで大らかにプログラムするようにします。


 次はT3です。
こちらはマスタ側が送信を終了してから通信方向を切り替えるまでの処理待ち時間です。この切り替え処理は割り込み処理関数内で記述できるので、それ程多くの待ち時間は必要ありません。T2の待ち時間を決めた方法を参考にして今度はマスタ側でUSARTの送信割り込みが受け付けられるまでの最悪条件を見つけ、その処理時間にマージンを付加した時間で設定します。

 T4はマスタ側での受信割り込み処理が受け付けられるまでの時間です。決め方もT2とほぼ同じです。

 最後はタイムアウトT5ですが、これはマスタ側でのT1と同じ考え方で決めることが出来ます。ただしマスタとスレーブが逆になりますが。

 以上で待ち時間を決める一通りの基準は説明しました。
最初から性能一杯の仕様で動かすのではなく、非常に大らかに十分なマージンを確保して動作させることが何よりも重要です。

目次へ  前へ  次へ