5

I cannot seen to get the serial port set up correctly using the termios structure so i am looking at third party libraries.

I have been advised to try boost.asio but when looking through the examples it appears that it does not support mark and space parity, is this true?

If it is possible could someone show example code on how to do mark and space parity in boost.asio. I am using 8 databits, 115220 baud rate and 1 stop bit.

Does anyone know of any third party libraries that support mark and space parity on linux that I can use instead of boost?

dsolimano
  • 8,870
  • 3
  • 48
  • 63
Skeith
  • 2,512
  • 5
  • 35
  • 57

1 Answers1

5

There is a very good article on this problem here.

In particular

MARK and SPACE parity, although implemented in most hardware, are not defined in the POSIX standard. The manpage of of the Unix/Linux termios library, for instance, doesn't loose a single word about these two parity modes. (Note that PARMRK has nothing to do with MARK parity.)

This is why, I think, these options are not implemented in Boost.Asio.

There are a number of solutions suggested: For example:

The mode 8M1 (8 data bits, MARK parity, 1 stop bit) can be emulated with 8N2. Instead of sending a parity bit and a stop bit, two stop bits are transmitted. Since stop bits are always 1 (mark bits), the two modes are equivalent.

If these don't match your requirements then you can get the native representation of your serial port in boost asio. From the docs:

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.

To get an idea of usage have a look at

boost_1_45_0/boost/asio/serial_port_base.hpp

and in particular the code to do with parity on 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;
  }

I think you want to use the native_handle to set set the flag something like so:

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

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

(according to here, anyway) Also see wrong sequence of libserial received data

Community
  • 1
  • 1
Tom
  • 5,219
  • 2
  • 29
  • 45
  • the examples you give are the termios structure that i could not get to work and CMSPAR is undefined on my system and does not work. thanks for the answer anyway now i know i have to do it in java :( – Skeith Oct 18 '11 at 12:25
  • @Skeith - have a look at the link - you can emulate both Mark and Space by using an extra stop bit (Mark is easier) - This is directly supported by Boost.Asio without the need to play with unsupported CMSPARs. BTW - I'm not sure switching languages will help if your kernel doesn't support it. – Tom Oct 18 '11 at 12:29
  • we have a program in java that communicates with out device but was built by my predecessor. i just did not want to have to try and cut the serial code from it if possible as it will be a major job to rewrite the functionality code from c++ to java as all we are missing is the serial code for linux but i have no choice now. – Skeith Oct 18 '11 at 12:36