Възможен ли е паритет на маркировката и интервала при използване на boost.asio?

Не мога да настроя правилно серийния порт, използвайки структурата termios, така че гледам библиотеки на трети страни.

Бях посъветван да опитам boost.asio, но когато разглеждам примерите, изглежда, че не поддържа паритет за маркиране и интервал, вярно ли е това?

Ако е възможно, може ли някой да покаже примерен код за това как да се направи паритет за маркиране и интервал в boost.asio. Използвам 8 бита данни, 115220 бода скорост и 1 стоп бит.

Някой знае ли за библиотеки на трети страни, които поддържат паритет на маркировката и интервала в Linux, които мога да използвам вместо boost?


person Skeith    schedule 18.10.2011    source източник


Отговори (1)


Има много добра статия за този проблем тук.

В частност

Паритетът MARK и SPACE, въпреки че е приложен в повечето хардуер, не са дефинирани в стандарта POSIX. Страницата за ръководство на Unix/Linux termios библиотеката, например, не губи нито една дума за тези два режима на паритет. (Имайте предвид, че PARMRK няма нищо общо с MARK паритета.)

Ето защо мисля, че тези опции не са внедрени в Boost.Asio.

Предлагат се редица решения: Например:

Режимът 8M1 (8 бита данни, MARK паритет, 1 стоп бит) може да бъде емулиран с 8N2. Вместо да се изпращат бит за паритет и стоп бит, се предават два стоп бита. Тъй като стоп битовете винаги са 1 (маркиращи битове), двата режима са еквивалентни.

Ако те не отговарят на вашите изисквания, тогава можете да получите родното представяне на вашия сериен порт в boost asio. От документите:

basic_serial_port::native_handle

Get the native serial port representation.

native_handle_type native_handle();
This function may be used to obtain the underlying representation of the serial port. This is intended to allow access to native serial port functionality that is not otherwise provided.

За да получите представа за употребата, погледнете

boost_1_45_0/boost/asio/serial_port_base.hpp

и по-специално кода за паритет на linux:

switch (value_)
  {
  case none:
    storage.c_iflag |= IGNPAR;
    storage.c_cflag &= ~(PARENB | PARODD);
    break;
  case even:
    storage.c_iflag &= ~(IGNPAR | PARMRK);
    storage.c_iflag |= INPCK;
    storage.c_cflag |= PARENB;
    storage.c_cflag &= ~PARODD;
    break;
  case odd:
    storage.c_iflag &= ~(IGNPAR | PARMRK);
    storage.c_iflag |= INPCK;
    storage.c_cflag |= (PARENB | PARODD);
    break;
  default:
    break;
  }

Мисля, че искате да използвате native_handle, за да зададете флага нещо подобно:

cflag |= PARENB | CMSPAR // To select SPACE parity
cflag &= ~PARODD

cflag |= PARENB | CMSPAR | PARODD // to select MARK parity

(според тук, както и да е) Също така вижте грешна последователност от получени от libserial данни

person Tom    schedule 18.10.2011
comment
примерите, които давате, са структурата termios, която не можах да задействам, а CMSPAR е недефиниран в моята система и не работи. благодаря за отговора все пак сега знам, че трябва да го направя в java :( - person Skeith; 18.10.2011
comment
@Skeith - погледнете връзката - можете да емулирате както Mark, така и Space, като използвате допълнителен стоп бит (Mark е по-лесно) - Това се поддържа директно от Boost.Asio, без да е необходимо да играете с неподдържани CMSPAR. Между другото - не съм сигурен, че смяната на езици ще помогне, ако ядрото ви не го поддържа. - person Tom; 18.10.2011
comment
имаме програма в java, която комуникира с нашето устройство, но е създадена от моя предшественик. просто не исках да се опитвам да изрязвам серийния код от него, ако е възможно, тъй като ще бъде голяма работа да пренапиша функционалния код от c++ на java, тъй като всичко, което ни липсва, е серийният код за linux, но нямам избор сега. - person Skeith; 18.10.2011