Windows CE 6.0デバイスでのシリアル通信にOpenNETCF.IO.Serial(オープンソース、see serial code here)を使用するアプリケーションを作成しています。このアプリケーションは、Compact Framework 2.0のC#でコード化されています。私が記述しようとしている問題は、具体的にはこれらの細部に関連しているとは思えませんが、私はその点で間違っていることが判明するかもしれません。Serial、RS422、C#、TxDoneイベントが起動しない、データが受信されない
問題は、と思われるです(断続的な問題として私は確実に複製できません)。デバイス自体が再起動されるまで、データは送信されず受信されません。 Windows CEデバイスは、全く異なるアプリケーションを実行するシステムと通信します。この他のシステムを再起動して通信ケーブルを切断/再接続しても、Windows CEデバイスを再起動するだけでこの問題は解決されないようです。
この問題の唯一の兆候は、OpenNETCFの発火(OpenNETCF.IO.Serialクラスで "TxDone();"を探す)からのTxDoneイベントがなく、データが受信されていないことです。接続されたシステムがデータを送信しているという事実。
シリアル通信では、1〜255(0x01〜0xFF)の任意の文字値を送受信できます。ヌル値は破棄されます。
シリアル設定は、38400ボー、8データビット、パリティなし、1ストップビット(38400,8n1)です。私は入力と出力のバッファサイズを256バイトに設定しました。 DataReceivedイベントは、1つ以上の文字を受信するたびに発生し、メッセージが可変長であるため、出力バッファに1バイト以上のバイトがあると送信が行われます。
ハンドシェイクは使用されません。これはRS422なので、RX +、RX-、TX +、TX-の4つの信号しか使用されていません。
"DataReceived"イベントが発生しました。入力バッファからすべてのデータを読み込み、自分のバッファにDataReceivedイベントの外で余暇を解析するための自分のバッファを作成しました。コマンドメッセージを受け取ったとき、私は速い確認メッセージを送り返します。他のシステムがWindows CEデバイスからのコマンドメッセージを受信すると、速い応答メッセージが返されます。肯定応答メッセージは、それが単純な "ええ、持っている"ものとして意図されているので、それ以上の応答は得られません。 私のコードでは、複数のスレッドで送受信しているので、複数のスレッドで複数のメッセージを同時に送信しないようにlockキーワードを使用します。コードを二重にチェックすると、私はロックが張られていないことがわかりました。
この時点では、シリアル通信がどのように機能するかについて何か明白でないものがあるかどうか、空ではなく入力バッファから読み込むのではなく、変数やプロパティを設定する必要がある送信バッファ。
任意の洞察、チェックするオプション、提案、アイデアなどを歓迎します。これは何ヶ月間も私自身が取り組んできたことですが、私がここで受け取った答えやコメントがこの問題を理解するのに役立つことを願っています。前もって感謝します。
編集、2011年2月24日:
(1)私は、Windows CEデバイスは、およびでないすべてのブートアップと通信しているシステムのブートアップ時にエラーを再作成するように見えることができます。私も信号を見て、同相電圧が変動しますが、システムの起動時に発生するノイズの振幅は、問題が発生しているかどうかとは無関係のようですが、25Vのピークツーピークは問題ありません。問題が再現されるまで)。
問題はますます多くのハードウェアに関連していますが、私が見ている症状の原因を突き止めようとしています。信号を測定するために手を伸ばします。私の申し訳はありませんが、ハードウェア部品の部品番号は一切指定できませんので、使用されているコンポーネントを尋ねないでください。
の@ ctackeの提案ごとに、私はすべての送信は、保守のために同じ場所を通過し、確保したよう次のように(2)、私は入れスレッドの安全性が本質的である:
lock(transmitLockObj)
{
try
{
comPort.Output = data;
}
[various catches and error handling for each]
}
(3)UART OVERRUNを取得エラーで、<の10バイトが38400ボーで約300msecの時間間隔で送受信されていたテストで発生します。エラーが発生すると、次のループの繰り返しに進み、ReadFileを実行せず、TxDoneイベント(またはその他の行チェックプロシージャ)を実行しません。また、ポートを閉じて再オープンするだけで何も起こらないだけでなく、デバイスが稼働している間にソフトウェアをリブートしても何も起こりません。ハードウェアの再起動のみ。
マイDataReceivedイベントは次のとおりです。
try
{
byte[] input = comPort.Input; //set so Input gets FULL RX buffer
lock(bufferLockObj)
{
for (int i = 0; i < input.Length; i++)
{
_rxRawBuffer.Enqueue(input[i]);
//timer regularly checks this buffer and parses data elsewhere
//there, it is "lock(bufferLockObj){dataByte = _rxRawBuffer.Dequeue();}"
//so wait is kept short in DataReceived, while remaining safe
}
}
}
catch (Exception exc)
{
//[exception logging and handling]
//hasn't gotten here, so no point in showing
}
しかし、私はUARTオーバーランエラーを取得し始めたときのWriteFileの呼び出しだったテストの最初の時間をタイムアウトしました瞬時の後。正直なところ、私のコードがUARTのオーバーラン状態を引き起こすのを見ることができません。
思考?ハードウェアやソフトウェアに関連して、私はチェックするために考えることができるすべてをチェックしています。
私は過去に完全な.NETフレームワーク(Windows XP)で同様の問題を抱えていました。データが停止した場合にシリアルポートを閉じて再オープンするハックを追加しました。しかし、長期的な解決には理想的ではありません。閉じる/再開してもオンラインに戻すことができるかどうかはわかりません。 – Justin
バッファーが小さく、ボーレートが高い。 Cr * pが発生します。 –
@ハンス、メッセージの長さは可変ですが、最大の可能性のあるメッセージは〜50バイトと計算されています。シリアルのlibがバッファに1バイト以上あるかどうかをチェックするたびに、DataReceivedイベントが適切にトリガされると、理論上、256はまともなサイズであることがわかります。また、実用的な経験が理論を満たしていることをテストするためにバッファのサイズを変更しようとしましたが、バッファサイズは何も解決しませんでした。悲しいことに、テストのボーレートについては何もできません。 –