4

予期しないシリアルポートで奇妙な動作が見られるシステムがあります。以前、usb-to-serialアダプターでこれを時々見ましたが、今では、はるかに高い頻度で、ネイティブシリアルポートでも見ています。

システムは自動テストを実行するように設定されており、ポートを開いていないときにシリアルデバイスから大量のデータを出力するいくつかのタスクを最初に実行します。デバイスも自動的にリセットされます。tx/rx回線のみが接続されています。フロー制御はありません。

これらのタスクが完了すると、テストウェアはシリアルポートを開き、予期しない応答を受け取るため、すぐに失敗します。これを再現すると、ターミナルプログラムでシリアルポートを開くと、数キロバイトの古いデータ(ポートが閉じられたときに送信されたように見える)がすぐにフラッシュされることがわかりました。このプログラムを閉じると、期待どおりにテストを実行できます。

これを引き起こす原因は何ですか?デバイスが閉じている場合、Linuxはシリアルポートのバッファリングをどのように処理しますか?デバイスを開いて出力を送信させてから、読み取らずに閉じた場合、同じ問題が発生しますか?

4

1 に答える 1

5

Linuxターミナルドライバは、開かれていない場合でも入力をバッファリングします。これは、特に速度/パリティなどの場合に便利な機能です。適切に設定されています。

下位のオペレーティングシステムの動作を再現するには、ポートが開いたらすぐに、保留中のすべての入力をポートから読み取ります。

...
int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
        exit (1);

set_blocking (fd, 0);   // disable reads blocked when no input ready

char buf [10000];
int n;
do {
        n = read (fd, buf, sizeof buf);
} while (n > 0);

set_blocking (fd, 1);  // enable read blocking (if desired)

...  // now there is no pending input



void set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error ("error %d getting term settings set_blocking", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = should_block ? 5 : 0; // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                error ("error setting term %sblocking", should_block ? "" : "no");
}
于 2011-11-10T19:26:49.183 に答える