2011-02-10 3 views
3

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のオーバーラン状態を引き起こすのを見ることができません。

思考?ハードウェアやソフトウェアに関連して、私はチェックするために考えることができるすべてをチェックしています。

+0

私は過去に完全な.NETフレームワーク(Windows XP)で同様の問題を抱えていました。データが停止した場合にシリアルポートを閉じて再オープンするハックを追加しました。しかし、長期的な解決には理想的ではありません。閉じる/再開してもオンラインに戻すことができるかどうかはわかりません。 – Justin

+0

バッファーが小さく、ボーレートが高い。 Cr * pが発生します。 –

+0

@ハンス、メッセージの長さは可変ですが、最大の可能性のあるメッセージは〜50バイトと計算されています。シリアルのlibがバッファに1バイト以上あるかどうかをチェックするたびに、DataReceivedイベントが適切にトリガされると、理論上、256はまともなサイズであることがわかります。また、実用的な経験が理論を満たしていることをテストするためにバッファのサイズを変更しようとしましたが、バッファサイズは何も解決しませんでした。悲しいことに、テストのボーレートについては何もできません。 –

答えて

0

ありがとうございました。これは実際にハードウェアに関連しているように見えます。私はこれ以上の情報を提供することはできないのではないかと恐れていますが、可能な解決策やトラブルシューティングのステップに貢献した皆さんに感謝します。

1

すべては聞こえますが、あなたの観察ではそうではないことが示されます。

複数のスレッドから送信していると言われているので、最初に行うべきことは、シリアルオブジェクトインスタンスを呼び出す前に、すべての送信要求が1つの場所に来るような送信メカニズム。もちろん、スレッドの安全性が確保されていると言いますが、これらの呼び出しを1つの場所でシリアル化することで、コードを補強しやすくなります(さらにコードをメンテナンス/拡張可能にする)。

次は、Txを実行したときにイベントを設定したり、デバッガでブレークしたり、いくつかの境界期間内にTxDoneイベントが発生しないようにするために、シリアルライブラリに一時処理を追加しています。シリアルライブラリにはバグが存在する可能性があります(私を信頼してください、コードの作成者は間違いありません)。

+0

コード提案の同じ場所からの送信に続いて、パフォーマンスの変更はありませんが、保守性の点では同意します。シリアルライブラリでは、(1)ReadFileコールの直前にイベントを追加しました。(2)ReadFileコールの直後に、ReadFileタイムアウトの遭遇時に、(3)if ){DataReceived event}を使用します。私は、UART OVERRUNエラーを記録してしまいました。ここでは、ReadFileをもう一度実行しません。これまでDataReceivedイベントは、バイトをキューに入れて残ります。このテストでは、38400ボーで300ミリ秒ごとに<10バイトを使用しています。 –

関連する問題