前回のMS-DOS用ソフト改造の現場でドハマリしたので備忘録代わりに・・・。
今回、バーコードリーダ(以下BCR)を取り替える事になり、対応をしたのですが、シリアル通信でBCRからデータを受信する箇所で、どういう訳かデータ受信時に「受信オーバータイムエラー」になってしまう。
やりとり的には以前のBCRとコマンドこそ違うものの、ほぼ同じ。なので、シリアル通信部分はライブラリをそのまんま流用して、送受信するコマンドだけを書き換えていた訳ですわ。それならば、コマンドが違う・・・?とアタリをつけて調べるものの、問題なし・・・。printfデバッグしまくって、とりあえず送信箇所には問題がないことを確認。となると、返信データを受信する箇所に絞られた訳ですわ。でも、ここからが進まない・・・。
はてさて、困ったぞ?と思っていると、よく現場で一緒になる別の会社の先輩プログラマの人がやってきて・・・「こんなとこで時間くうなよ~pgr」(冗談を言い合えるくらいには仲良い人ですw)と、言って去っていった数十分後に同じところでハマっていると戻ってきたりwww
今回の改造、何箇所かの検査機に対してやっているんですが、問題なく動いている箇所もある。
では、動いているところとの差って何なんだ?と考えると、コンパイラがMS-CかBCCの違いがあることに気付いた訳です。
そこに気付いて更に数時間・・・先ほど私にpgrしていった人がトラップに気付いたんですな。
このBCR、送信文字列の最後にデリミタとして、「0x0D」をくっつけて返事してくるんですわ。
シリアル通信の送受信用のライブラリの中身を覗いてみると、デリミタ判定に使用されている文字が「¥n」だったんですな。
リリースの15年後に発動したトラップ・・・あなおそろしや・・・w
これが孔明の罠か!?
RE: これが孔明の罠か!?
MS-CとBCCではシリアル通信のデフォルトのオープンモードが違うということですか?
テキストモードでたまたまうまく動いていたということですよね。
テキストモードでたまたまうまく動いていたということですよね。
最後に編集したユーザー ISLe on 2013年11月05日(火) 16:22 [ 編集 1 回目 ]
RE: これが孔明の罠か!?
動いたのに安心して細かく調べた訳ではないので推測ですが、MS-Cでは「¥n」はCRLF(0x0D, 0x0A)に内部で置換されているようなのですが、BCCではLF(0x0A)だったのでは・・・?と思っています。
この推測が正しければ、前者は0x0Dを受信した時点で文字列の終端とみなせますので、0x0Aというゴミデータを受信しつつも正常に動いているように見えますが、後者は0x0Dを受信することができないので受信オーバータイムを引き起こしていたという訳です。
この推測が正しければ、前者は0x0Dを受信した時点で文字列の終端とみなせますので、0x0Aというゴミデータを受信しつつも正常に動いているように見えますが、後者は0x0Dを受信することができないので受信オーバータイムを引き起こしていたという訳です。
RE: これが孔明の罠か!?
文字列リテラル上で変換されることはないのでオープンモードに起因する問題のはず。
テキストモードでの改行コードに対する処理の違いが原因という線を思い付きました。
・MS-Cはテキストモードで0x0d(\r)単独でも0x0a(\n)単独でも0x0d,0x0aに変換するから0x0a(\n)に引っ掛かる
・BCCはテキストモードで0x0a(\n)単独を0x0d,0x0aに変換するが0x0d(\r)単独は変換しないから0x0a(\n)に引っ掛からない
ということではないかと想像します。
テキストモードでの改行コードに対する処理の違いが原因という線を思い付きました。
・MS-Cはテキストモードで0x0d(\r)単独でも0x0a(\n)単独でも0x0d,0x0aに変換するから0x0a(\n)に引っ掛かる
・BCCはテキストモードで0x0a(\n)単独を0x0d,0x0aに変換するが0x0d(\r)単独は変換しないから0x0a(\n)に引っ掛からない
ということではないかと想像します。