シリアル通信を使ってデータの送受信をしています。
画面に表示するものは、
送信したコマンド(文字列(固定長))
受信したコマンド(文字列(固定長))
CRLFを受信した時点で解析し正しく受信されたかなどの判定をして
それをファイルへ保存ということをやっています。
コマンドは100msごとに送信します。
問題は他のアプリなどが起動や実行されていると自アプリの処理に時間がかかってしまいオーバーランが起こってしまいます。ドライバのせいではありません。
プログラミングを始めてからまもないため、どのように解決していいかわかりません。
高速化が出来そうなヒントがありましたらよろしくお願いします。
これだけだと何とも言えません。
もしかして、保存に100ms以上かかってしまって、タイミングがずれる、ということでしょうか。
送受信部分をスレッド化してループさせ、CRLFが入ったら別スレッドでファイル保存、というようにしてはどうでしょう。
> もしかして、保存に100ms以上かかってしまって、タイミングがずれる、という> ことでしょうか
送信するタイミングが100msごとに送っています。
> 送受信部分をスレッド化してループさせ、CRLFが入ったら別スレッドでファイル> 保存、というようにしてはどうでしょう
スレッド化は考えたのですが、同期の取り方とかがよくわからず
途中まで作成して「他の方法のほうがいいんじゃないか」と思って違うことをいろいろ試しましたが、どれも駄目でした。
やり方が間違っていても、自分の知識にあったヘルプやサンプルがないために
悩んでいます。
どこにどれだけの時間がかかっているかはわかりません。
それを調べるためには、やはりGetTickCountで調べるんですか?
オーバーランしているというのはどこで判断しました?
そのオーバーランしている箇所から、逆に辿れば悪い場所はわかってくると思います。
誤差があってよいのであれば、GetTickCountでもいいと思います。
100msごとというのは、どうやって100msにしていますか?TTimerを使うと少しずれるかもしれません。
# ずれても問題ないと思いますが
少し難しくても、Thread化したほうが良い気がします。
Threadを作るのはそう難しいものでなく、TThreadを継承したクラスを作り、Executeプロシージャをoverrideするだけです。
たとえば、
procedure TMyThread.Execute;
begin
while not Terminated do
begin
{ データ受信 }
{ 受信したデータが正しいかの判断と出力 }
Sleep(100); // 100ms停止
end;
end;
という形です。
送信が失敗しているか、受信が失敗しているか、どちらかはわかっていますか?
まずはそれを確かめるべきです。
ドライバのせいではないとありますが、ドライバにはバッファはないのでしょうか。通常、バッファに貯まったデータを受信しに行くので、取りこぼしなどは発生しないはずです。
にしの様、丁寧なお返事ありがとうございます。
> オーバーランしているというのはどこで判断しました?
> 送信が失敗しているか、受信が失敗しているか、どちらかはわかっていますか?
受信文字列を画面に表示してあるのを見てです。
例えば'abcdefg'という固定長を送信したら受信文字列は'abcdabcdefg'となっていました。毎回ではないです。
> 100msごとというのは、どうやって100msにしていますか?
TTimerを使っていました。
> ドライバのせいではないとありますが、ドライバにはバッファはないのでしょうか
ドライバ側でオーバーランが起こった場合、メッセージが出るようにしてあるのですが、この場合だと、アドレス違反(書き込み違反)が出ていたのでそうではないかと思ったのです。
課題の提出が迫っていたために、パニックにおちいってしまってわかるものもわからなくなってしまっていたみたいです。TThreadもそんなに難しいものではなかったみたいです。今になってから言える事ですけど・・・
スレッド化したおかけで、オーバーランが起こらなくなりました。ほんとに親切に教えていただいてありがとうございます。