C ++ последовательная связь Linux 9 бит данных - PullRequest
2 голосов
/ 26 октября 2011

немного экзотический вопрос: D

Я программирую на C ++ в Ubuntu 10, и мне нужно кодировать протокол mdb (multi drop bus), который использует 9 бит данных в последовательной связи (ДА 9 битов данных:D)

Некоторые драйверы поддерживают 9 битов данных на некоторых микросхемах Uart, но в основном они этого не делают.

Для краткого пояснения: mdb использует 8 битов данных для данных и 9-й бит данных для режима,Таким образом, когда ведущий отправляет первый BYTE, он устанавливает mode = 9thbit в 1, что означает, что все устройства на шине прерываются и ищут этот первый байт, который содержит адрес устройства.Если прослушивающее устройство (одно из многих) находит свой адрес в этом первом байте, оно знает, что следующие байты будут для него байтами данных.байты данных имеют бит 9 = бит режима, установленный в 0

пример в битах: 000001011 000000010 000000100 000000110 (1-байтовый адрес и 3 байта данных)

Ситуация возврата из бита ведомого -> главного режимаиспользуется для окончания передачи.Таким образом, мастер считывает данные из последовательного порта до тех пор, пока не найдет 9-битный пакет с 9-м битом = 1, обычно последняя 9-битная последовательность является байтом chk + mode = 1

Итак, наконец, мой вопрос:

Я знаю, как использовать флаг CMPAR в termios, чтобы использовать бит четности для бита режима, например.установка его в значение MARK (1) или SPACE (0)

пример FOR ALL, который не знает как:

Сначала проверьте, определено ли это, если, вероятно, нет поддержки в termios:

    # define CMSPAR   010000000000      /* mark or space (stick) parity */

И код для отправки с меткой или пробелом например.имитация 9-го бита данных

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

    if(useMarkParity)
    {
            // Send with mark parity
            tio.c_cflag |= PARENB | CMSPAR | PARODD;
            tcsetattr(portFileDescriptor, TCSADRAIN, &tio);

    }
    else
    {
            // Send  with space parity
            tio.c_cflag |= PARENB | CMSPAR;
            tio.c_cflag &= ~PARODD;
            tcsetattr(portFileDescriptor, TCSADRAIN, &tio);
    }
    write(portFileDescriptor,DATA, DATALEN);

Теперь то, что я не знаю, КАК установить проверку четности при получении, я перепробовал почти все комбинации и не могу получить эту последовательность байтов четности ошибок.

Может ли кто-нибудь помочь мне, как настроить проверку четности при получении, что он не игнорирует четность и не обрезает байты, но добавляет DEL до «плохого» полученного байта:

Как сказано в справке POSIX Serial

INPCK и PARMRK Если включен IGNPAR, в вашу программу перед каждым символом с ошибкой четности отправляется символ NUL (в восьмеричном виде).В противном случае, символы DEL (177 восьмеричных) и NUL отправляются вместе с неверным символом.

Как правильно установить PARMRK AND INPCK, чтобы он обнаруживал бит режима = 1в качестве ошибки бита четности и вставьте восьмеричное значение DEL 177. В обратном потоке.

Спасибо: D

Ответы [ 2 ]

1 голос
/ 26 октября 2011

Мне кажется, что вы хотите установить паритет пространства на приемнике и не включать IGNPAR.Таким образом, когда байт с меткой четности получен, он должен генерировать ошибку четности с помощью DEL.

0 голосов
/ 25 ноября 2013

У меня была такая же проблема при работе в гостевой ОС Linux. Запуск той же программы на другом компьютере с Linux в качестве операционной системы хоста. Я подозреваю, что виртуальный последовательный порт не передает ошибку четности. См. поведение PARMRK termios не работает в Linux . Все еще возможно, что виртуальная машина не является проблемой, потому что это был совершенно другой компьютер. Однако я смог получить ошибки четности, используя Realterm в Windows (хост-ОС на компьютере, где Linux был гостем).

Также обратите внимание, что код в n_tty.c показывает, что он вставляет '\ 377' '\ 0' вместо '\ 177' '\ 0'. Это также было проверено на рабочей конфигурации.

...