I'm working on an existing driver that controls an 8-bit MCU over a serial port. There are many different flavors of firmware for the MCU but they all share a common method of trying to ensure link integrity. This method is not very robust and I am looking for ideas about how the driver could modify its behavior to get the most out of it.

Commands are gcode with a line number and a checksum:

N3 T0*57
N4 G92 E0*67
N5 G28*22
N6 G1 F1500.0*82
N7 G1 X2.0 Y2.0 F3000.0*85
N8 G1 X3.0 Y3.0*33

The line number must be sequential (but can be reset with M110). If the checksum doesn't match or the line number is out of sequence the firmware will reply Resend: nnn where nnn is the last successful N plus 1. The "checksum" is extremely primitive:

        // Calc checksum.
        byte checksum = 0;
        byte count = 0;
        while(instruction[count] != '*')
                checksum = checksum^instruction[count++];

The main problem is that the primary error mechanism is dropped bytes due to interrupts being held off leading to overflows in the 1-byte MCU FIFO. The actual serial bus is a few cm between an FTDI (or similar) USB serial bridge and the MCU, so bit errors are unlikely. I've never observed a bit error in a reply from the firmware.

As you can see, the algorithm above would detect one dropped byte, but if you dropped two of the same byte (anywhere!) the result would still match. Thus F3000.0 (feedrate 3000mm/min) could be transmuted to F30.0 and still match. Plus, the character set is very small so certain bits are never going to be involved.

Is there anything the driver can do to make a given line more robust?

  • Add or drop trailing (or even leading) zeroes
  • Add or drop spaces
  • Re-order words (X1 Y1 is the same as Y1 X1)
  • Edit
    Report