UART binary issue - might help others



  • I recently moved some code over from a project I had running on HLK-7688A devices.
    It uses RS485 to communicate with other devices.

    I simply re-compiled the code using the Onion cross-compiler and it all seemed to work nicely.

    Except one thing...
    Every now and then I would get a corrupt message from a remote device. A chksum embedded in the protocol would not match, and ocasionally a length byte in the received bytes would be wrong too.
    I thought it might be just a noisy RS485 line but when probing the actual RX line going into the Omega showed a perfectly valid signal.

    On the wire the bytes would look something like this (in hex):

    21 24 56 58 0D 00 01 00
    

    But in the app the bytes being read() from the port would be something like:

    21 24 56 58 0A 00 01 00
    

    Thing is that the error was consistently the same error. Not like noise or random bits being flipped. Always the exact same corruption. I had never seen this before, this code had run fine on the HLK-7688A

    It turns out that it was the terminal options I was setting on the file descriptor of the port I opened using open().
    After opening the port with

    fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
    

    I then use tcgetattr and tcsetattr to get the port options and modify things like the baudrate, parity, flow-control etc. I was using this:

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

    But I had to change it to :

    options.c_iflag &= ~(IXON | IXOFF | IXANY | ISTRIP | ICRNL);
    

    To stop the pre-parser stripping the 8th bit from bytes and to stop it converting 0D to 0A (ie. CR to NL).

    This is a bit of a simplified explanation, but it shows it pays to be careful with the options flags!
    Funny how this never came up on the HLK-7688A - but they do use a very different build from OpenWRT.


Log in to reply
 

Looks like your connection to Community was lost, please wait while we try to reconnect.