6

Linux でシリアル ポート、特に ttyUSB を使用する必要があるアプリケーションを作成しました。読み書き操作は、標準の select()/read() ループと write() で実行され、おそらく何も問題はありませんが、初期化コード (またはその一部の欠如) が tty サブシステムの何かを損傷します。ここにあります:


  vuxboot(string filename, unsigned baud = B115200) : _debug(false) {
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY);
    if(_fd < 0) throw new io_error("cannot open port");

    // Serial initialization was written with FTDI USB-to-serial converters
    // in mind. Anyway, who wants to use non-8n1 protocol?

    tcgetattr(_fd, &_termios);

    termios tio = {0};
    tio.c_iflag = IGNPAR;
    tio.c_oflag = 0;
    tio.c_cflag = baud | CLOCAL | CREAD | CS8;
    tio.c_lflag = 0;

    tcflush(_fd, TCIFLUSH);
    tcsetattr(_fd, TCSANOW, &tio);
  }

もう 1 つtcsetattr(_fd, TCSANOW, &_termios)はデストラクタにありますが、これは無関係です。

この用語の初期化の有無にかかわらず、アプリケーションの終了後にシステムで奇妙なことが起こります。プレーンcat(またはhd)が毎回何も出力しないか同じものをすぐに終了する場合があります。ポートに確実に送信されるデータを待機して表示しない場合もあります。そしてclose()read()毎回ではありませんが)usb-serial.c を参照しWARNINGて dmesgに奇妙なメッセージを出力します。

ハードウェアとファームウェアを何十回も (別のマシンでも) チェックしましたが、意図したとおりに動作していると確信しています。さらに、同じメッセージを何度も出力するようにファームウェアを削除しました。

何も破壊せずにシリアルポートを使用するにはどうすればよいですか? ありがとう。

4

5 に答える 5

2

WARN_ON行にヒットしたということは、カーネルのバグに遭遇したことを意味している可能性があります。最近、USB シリアル ドライバを改善するために多くの作業が行われていることは知っています。新しいカーネルを試すか、linux-usb@vger.kernel.org メーリング リストで質問することをお勧めします。

于 2010-06-06T01:31:59.870 に答える
1

そこにあるコードのスニペットの何が問題なのかわかりませんが、まだ見ていない場合は、これが役立つかもしれません: POSIX オペレーティング システムのシリアル プログラミング ガイド

ごく最近、いくつかのシリアル ポート インターフェイスを作成する必要がありましたが、このライブラリは正常に動作しました。これは、別の例として役立つ可能性があります。

于 2010-06-05T23:43:42.320 に答える
0

わかった。これは完璧な解決策ではないかもしれません...絶対にそうではありません。FT232コンバーターを捨てて(実際には揚げました)、CP2102ベースのコンバーターを使用しました。それは今すぐ機能します(また、6倍安くなります)。

于 2011-07-05T21:26:17.563 に答える
0

余談ですが、あなたのエラー チェックopenは正しくありません。エラー状態は、戻り値 -1 によって通知されます。(0 は完全に有効な fd で、通常は stdin に接続されています。)

于 2010-06-06T08:58:43.917 に答える
0

あなたは試してみたいかもしれません:

  vuxboot(string filename, unsigned baud = B115200) : _debug(false) {
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY);
    if(_fd < 0) throw new io_error("cannot open port");

    // Serial initialization was written with FTDI USB-to-serial converters
    // in mind. Anyway, who wants to use non-8n1 protocol?

    tcgetattr(_fd, &_termios);

-   termios tio;
+   termios tio;
+   memcpy(&tio, &_termios, sizeof(struct termios)); 

    tio.c_iflag = IGNPAR;
    tio.c_oflag = 0;
    tio.c_cflag = baud | CLOCAL | CREAD | CS8;
    tio.c_lflag = 0;

    tcflush(_fd, TCIFLUSH);
    tcsetattr(_fd, TCSANOW, &tio);
}

これによりtermios、システム上の予期しないフィールドがある程度妥当な値になるようになります。

于 2010-06-06T18:42:22.380 に答える