PRS-DE07MS通信基礎実験・DORエラー調査
すいません m(_ _)m、本記事はブログ引越時に書式が崩れました。順次修正中です。
“DOR”ってのは、データオーバーランエラーのことです。PRS-DE07MS通信基礎実験の中で、USART0(パソコン側)と同時に通信しているときに、384kbpsでPRS-DE07MSと通信すると、DORが発生するということを書きましたが、なんとなく気持ち悪いので、再度、調査してみました。
■うまく動作したソースコードと問題ありのソースコード
まず、対象部ですが、「PRS-DE07MS通信基礎実験・まとめ その2<http://siso-lab.net/20090314075900/>」にてアップしたソースコードの以下の部分です。
208: // PRSからの応答が速いと、USART0(パソコン側)に文字列を送っている 209: // 間にバッファオーバーランが発生することがあるので、PRSに送る前に 210: // パソコンへの文字列送信をやりきってしまう。 211: rs0_puts_P( PSTR("]...RECV [")); 212: 213: // 本当はここでrs0_tx_buff()を使いたいのだが、なんとなく動きが微妙だった 214: // ので、かわりに手抜き0.1secタイマで送信完了しただろう時間待つ。 215: for( ulTimer = 0L; ulTimer < 41667L ; ulTimer++ ); 216: 217: // コマンドの送信 218: send( aucSendBuff, ucCnt ); 219: 220: // データ受信 221: // データ受信を実行し、受信結果が問題なければそのまま受信データを 222: // 表示し、異常の場合は異常値を表示する。 223: ucRecvRes = recv( aucRecvBuff, &ucLen );
この部分を次のようなコードにしていたら、DORが発生しました。行番号は抜いてありますが、ポイントは、「rs0_puts_P( PSTR(“]\n”));」から「ucRecvRes = recv( aucRecvBuff, &ucLen );」の間です。無駄に「rs0_printf_P()」を使っていますが、あれこれ試していたときのコードですので、御勘弁ください。
rs0_puts_P( PSTR("]\n")); // コマンドの送信 send( aucSendBuff, ucCnt ); // データ受信 rs0_printf_P( PSTR("\n...RECV [")); ucRecvRes = recv( aucRecvBuff, &ucLen );
で、あれこれ試行錯誤しているうちに最終的なソースコードになり、USART0に送信バッファから割込みで送信し続けている状態の場合は、USART1の読み取り処理が間に合わなくなることもあるだろうという結論になったのですが、ならばと思い、以下のようなソースコードにしてみました。
// PRSとの送受信中もUSART0通信が行われるように、55バイトほどUSART0にて // 送信する。 rs0_puts_P( PSTR("]......... ......... ......... ......... ........RECV [")); // コマンドの送信 send( aucSendBuff, ucCnt ); // データ受信 ucRecvRes = recv( aucRecvBuff, &ucLen );
明確にUSART0の送信中状態を作ろうと思い、PRS-DE07MSへコマンドを送信する前に、長いデータをUSART0処理の方へ渡すようにしました。GDL付属ライブラリのソースコードを見ていただければわかりますが、「rs0_puts_P()」を実行すると、渡されたデータをバッファ変数にコピーし、以降、1バイト分の送信が完了するたびに割込みが発生し、さらに1バイト送信する、という動きになります。
「55バイト」というのは、115kbpsで通信した場合、約5msec程度になります。PRS-DE07MSの送受信をしている間、というのが目的ですので、これで十分かと思います(たぶん、1msec未満でも十分だと思います)。「よし、これでDORエラーだ!」と思って実行してみたところ…
問題なく通信できました。○| ̄|_
■一番もっともらしい推測
あれこれ推測してみた結果、以下のような推測にたどり着きました。
- PRS-DE07MSにデータを送信する。
- rs0_printf_P()を使ってUSART0の送信バッファにデータをコピー…ここで時間がちょっと必要。
- 「2.」をやっている間にPRS-DE07MSから返事。
- 「2.」のコピーが終わったら、USART1の受信処理に入る。
- でも、USART1からの3バイト目の取り出しが間に合わない。
- DORエラー発生。
というわけで、USART1をメイン処理でやっていて、しかも、PRS-DE07MSへの送受信処理の間に、USART0用の送信バッファにデータをセットしているのが敗因かと思われます。だとすると、ちょっとしょうもない系ミスです。
というわけで、USART1も割込み処理化したプログラムを作って試してみようと思います。
Your Message