2

アドレス バイトにマーク パリティを使用し、メッセージ本文にスペース パリティを使用するデバイスからメッセージを受信しようとしています。デバイスは、マルチドロップ シリアル バスの「マスター」です。termios のマニュアル ページに基づいて、私は CMSPAR、PARENB、~PARODD、INPCK、~IGNPAR、および PARMRK を使用しています。各アドレス バイトで '\377' '\0' の 3 バイト シーケンスを取得することを期待しています。それは起こりません...私は常にアドレスバイト(および本体バイト)を取得しますが、先頭の '\377' '\0' 文字は取得しません。

CMSPAR がサポートされていない場合に備えて、奇数パリティと偶数パリティのセットアップで PARMRK を動作させようとしました。データ ストリームにはまだ 3 バイト シーケンスはありません。Ubuntu 12.04 LTS を使用しています。

n_tty.c: n_tty_receive_parity_error() には PARMRK を実装するロジックがあります。8250_core.c には、パリティ エラーにフラグを立てるロジックがあります。dmesg | grep ttyS0 は serail8250 を示しています: ... は 16550A です。うーん... 後続のメッセージは 00:0a を示しています: ... は 16550A です。おそらく、8250 ドライバーは実際には ttyS0 を処理していないのでしょうか?

何か案は?私が何を間違えたのか分からなくても、PARMAR が機能するようになった場合でも、あなたの状況についてのコメントが助けになるかもしれません。

更新: 私の Linux は VMware VM で実行されているため、VM 以外の構成を試してみたところ、動作するようになりました! 誰かが知っている場合、VMでパリティエラーが検出されない理由を知りたいです。

ここに私の設定コードがあります:

struct termios tio;
bzero(&tio, sizeof(tio));
tcgetattr(fd, &tio);

// Frame bus runs at 38,400 BAUD
const int BAUD_Rate = B38400;

cfsetispeed(&tio, BAUD_Rate);
cfsetospeed(&tio, BAUD_Rate);

// Initialize to raw mode. PARMRK and PARENB will be over-ridden before calling tcsetattr()
cfmakeraw(&tio);

// Ignore modem lines and enable receiver
tio.c_cflag |= (CLOCAL | CREAD);

// No flow control
tio.c_cflag &= ~CRTSCTS;        // No HW flow control
tio.c_iflag &= ~(IXON | IXOFF); // Set the input flags to disable in-band flow control

// Set bits per byte
tio.c_cflag &= ~CSIZE;
tio.c_cflag |=  CS8;

// Use space parity to get 3-byte sequence (0xff 0x00 <address>) on address byte
tio.c_cflag |=  CMSPAR;         // Set "stick" parity (either mark or space)
tio.c_cflag &= ~PARODD;         // Select space parity so that only address byte causes error

// NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
tio.c_cflag |=  PARENB;         // Enable parity generation
tio.c_iflag |=  INPCK;          // Enable parity checking
tio.c_iflag |=  PARMRK;         // Enable in-band marking 
tio.c_iflag &= ~IGNPAR;         // Make sure input parity errors are not ignored

// Set it up now
if (tcsetattr(fd, TCSANOW, &tio) == -1)
{
    cout << "Failed to setup the port: " << errno << endl;
    return -1;
}
4

1 に答える 1