アドレス バイトにマーク パリティを使用し、メッセージ本文にスペース パリティを使用するデバイスからメッセージを受信しようとしています。デバイスは、マルチドロップ シリアル バスの「マスター」です。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;
}