C++ – Linux and Windows serial port communication

Linux and Windows serial port communication… here is a solution to the problem.

Linux and Windows serial port communication

I’m sending data bytes from linux to windows via serial RS232 and then everything works fine, only I have to deal with the 0xa sent from linux because windows reads it as 0xd + 0xa.
But when I send data bytes from Windows to Linux, some bytes are replaced with –
Windows Send – 0xd Linux receives 0xa
Windows Send – 0x11 Linux receives an integer garbage type value of 8200

Please explain what went wrong when I sent data from Windows to Linux.
Thanks in advance

Windows serial port initialization

char *pcCommPort = "COM1";
    hCom = CreateFile( TEXT("COM1"),
                       GENERIC_READ | GENERIC_WRITE,
                       0,    // must be opened with exclusive-access
                       NULL, // no security attributes
                       OPEN_EXISTING, // must use OPEN_EXISTING
                       0,    // not overlapped I/O
                       NULL  // hTemplate must be NULL for comm devices
                       );
fSuccess = GetCommState(hCom, &dcb);
 FillMemory(&dcb, sizeof(dcb),0);

dcb. DCBlength = sizeof(dcb);
    dcb. BaudRate = CBR_115200;      set the baud rate
    dcb. ByteSize = 8;              data size, xmit, and rcv
    dcb. Parity = NOPARITY;         no parity bit
    dcb. StopBits = ONESTOPBIT;     one stop bit
    dcb.fOutxCtsFlow = false;

fSuccess = SetCommState(hCom, &dcb);
 buff_success = SetupComm(hCom, 1024, 1024);
COMMTIMEOUTS cmt;
     ReadIntervalTimeout in ms
    cmt. ReadIntervalTimeout = 1000;
    cmt. ReadTotalTimeoutMultiplier = 1000;
    cmt. ReadTotalTimeoutConstant=1000;
    timeout_flag = SetCommTimeouts(hCom, &cmt);

Windows writes serial port –

WriteFile(hCom, buffer, len, &write, NULL);

Linux serial initialization –

_fd_port_no = open("//dev//ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(_fd_port_no, &options);
        cfsetispeed(&options, B115200);
        cfsetospeed(&options, B115200);
        options.c_cflag |= (CS8);
        options.c_cflag|=(CLOCAL| CREAD);
        options.c_cflag &=~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
        options.c_iflag |= (IXON | IXOFF | IXANY);
        options.c_cflag &= ~ CRTSCTS;
        tcsetattr(_fd_port_no, TCSANOW, &options);

Read serial port linux-

while(read(_fd_port_no,buffer+_buffer_len,sizeof(buffer))>0)
    {
        _buffer_len = _buffer_len+sizeof(buffer);

}

Yes, as I said, only NL/CR issues were detected from Linux to Windows, but I solved it with byte substitution,
But do you know the serila data sent from Windows to Linux (byte substitution policy).
I actually have to send a 200 KB file in a 200-byte block serially so that if sent from Windows to Linux, which byte can be replaced

Solution

If you’re using ReadFile and WrietFile on Windows and read and write on Linux, it really matters what it should be at the end of the line, except “you have to translate it sometime after receiving it.”

This doesn’t look right :

while(read(_fd_port_no,buffer+_buffer_len,sizeof(buffer))>0)
{
    _buffer_len = _buffer_len+sizeof(buffer);

}

You should consider the read size returned by read.

If sizeof(buffer) is the actual buffer you are reading into, add +_buffer_len when _buffer_len >= sizeof(buffer) will be written out of the buffer.

Also a little worried about this :

    options.c_iflag |= (IXON | IXOFF | IXANY);
    options.c_cflag &= ~ CRTSCTS;

Are you sure you want to use XOFF/CTRL-S (0x13) to stop the stream? Usually this means that data containing CTRL-S is not allowed – this may not be a problem when sending text data, but if you need to send binary data, it definitely will. IXOFF also means that the other end must respond to XOFF and XON (CTRL-Q, 0x11) to stop/start the data flow. In general, we do not want this to happen in modern systems….

If the wiring at both ends is correct, it should be safe to use RTS/CTS.

Related Problems and Solutions