掲示板とか見ていると、無手順通信大好きで、無手順でシリアル通信して、データの欠落で困っている人をときどき見かける。開始終端符号やチェックサムすら付けず、ほんとに何もなしで通信してるのだからデータが欠落する場合があるのは当たり前だし、当たり前のことなんだから「仕様です」って受け入れればよいのにといつも思う。
言っておくがデータは欠落したり、エラーで壊れるものだ。エラーになってもリカバリの必要がないと判断したうえで、無手順を選択するのはわかる。あるいは下位のレイヤーでエラー訂正などの手順をサポートしているから上位のレイヤーが無手順なのはわかる。
でも下位の手順がエラー訂正などのプロトコルをサポートしていない状態で、上位レイヤーで無手順通信して、エラーが起きてて困るって「何を考えてるの?」としか言いようがない。
といっても、前任者が馬鹿で無手順通信で設計した上に、相手機器は更新不可で泣いているひともいるのかもしれない。愚痴ってばかりでもなんなので、現実的な解決方法を挙げておこう。
PCIバスに接続する通信ボードを使う
オンボードの232Cでも16バイトのFIFOバッファがあるのて大丈夫そうだが、Windowsって数十ms程度の処理遅れは珍しくないんだ。フロー制御もソフトウェア側でやることになるので、オンボードの16バイト程度だと簡単にオーバーランエラーが発生する。PCIバスに接続するタイプだと128バイト程度のFIFOバッファを備えているのが多いのでわりと大丈夫だ。
予算的に可能なら、フロー制御までボード側でやってくれるインテリジェント232Cボードとか使うともっと安心だけどね。
USB接続の232Cポートは避ける
「USBってエラーも発生しないし、高速だし良いかな」と思ってるなら幻想だからね。USBの欠点の一つがオーバーヘッドが大きいことです。
USB2.0ではバスを複数のデバイスで時分割多重化によって共有します。ひとつのデバイスが125μsの間バスを占有したら、次のデバイスが再び125μsの間バスを占有します。こんな感じで動作するので負荷の状態によっては、数十ms程度の遅延が発生する場合があります。負荷が高いときにUSB接続のマウスが動きにくくなることを経験した事がありますよね。
そのためENQ-ACKを定周期で送受信するような通信プロトコルや、相手デバイスのバッファサイズが小さく制御線の状態を頻繁に読み取ったり、制御線の状態を細かく制御するような場合に、タイミングが安定せずに障害の要因になることがあります。
シリアルポートの仕様確認
オンボードのシリアルポートはチップセットの仕様上制御線が無い事もある。その場合CS/RSやDTR/DSRを使ったフロー制御は出来ない。「オンボードでシリアルあるから大丈夫だよね。」などと安易に判断して、後から制御線が繋がってない事に気がついても、ソフトウェアではどうにも出来ない。最初にきっちり仕様を確認するのが重要。