Я пытаюсь получать сообщения от устройства, которое использует контроль четности для байта адреса и контроль четности пробела для тела сообщения. Устройство является «мастером» многоабонентской последовательной шины. Основываясь на справочной странице termios, я использую CMSPAR, PARENB, ~PARODD, INPCK, ~IGNPAR и PARMRK. Я ожидаю получить 3-байтовую последовательность для каждого байта адреса: '\377' '\0' . Этого не происходит... Я всегда получаю байт адреса (и байты тела), но не начальные символы '\377' '\0'.
Я попытался заставить PARMRK работать с настройками нечетной и четной четности на тот случай, если CMSPAR не поддерживается. По-прежнему нет 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, поэтому я попробовал конфигурацию без виртуальной машины, и теперь она работает! Если кто-то знает, я все же хотел бы знать, почему ошибки четности не обнаруживаются на виртуальной машине.
Вот мой код конфигурации:
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;
}