8

I was wondering how to create a safe UART/USB communication protocol. I need it for the communication between a microcontroller and a PC. I have ~10 commands and thought I'd use 10 separate acknowledge commands for each of them.

The exchange should go like this:

  • PC sends wake up command via UART
  • µC recognizes that the PC is connected and sends his command to the PC, eg. 0x01
  • PC does what it was asked to (some hardware stuff) and responds with ~0x01 when it's done (I negate the number to create a larger "distance" between the two numbers)
  • µC knows that it sent 0x01 and is expecting ~0x01 from the PC. If something other than ~0x01 comes back, the µC will know that something went wrong and will send a new request or an error message

The case that the µC sends 0x01, the PC understands 0x02 and sends ~0x02 back but the µC reads ~0x01 due to some noise would be pretty bad.

How safe is that in terms of transmission, or how can I make this more secure?

Greg d'Eon
  • 3,807
  • 4
  • 24
  • 50
JavaForStarters
  • 183
  • 1
  • 12
  • 1
    You might want to review [the related question of mine](http://electronics.stackexchange.com/questions/186254/serial-protocol-delimiting-synchronization-techniques) and the very good answers to it. – Eugene Sh. Nov 09 '15 at 18:27
  • 1
    By "more secure" I take it you mean less prone to transmission errors, not adding crypto etc. to resist eavesdropping and what not. Even just that is a pretty vast field: https://en.wikipedia.org/wiki/Error_detection_and_correction – Fizz Nov 09 '15 at 18:49
  • You're right, it sounds a bit confusing. Transmission errors of course. I would activate the UART parity bit, since the µC supports it in hardware and it should be really quick, but it's still a bit unsecure, if just the right bits change due to noise... – JavaForStarters Nov 09 '15 at 18:59
  • 2
    You might want to look up [Hamming coding](https://en.wikipedia.org/wiki/Hamming(7,4)). It will take up to 16 commands (4 bits), and expand them in a systematic way to 7 bits (which can be transmitted over a standard UART). You can choose to correct any single bit error, or detect whether any two bits have been mis-received. – Neil_UK Nov 09 '15 at 19:12
  • 2
    1) 7 bit + a parity bit is one way and it is simple. It will not catch all possible errors but will catch many. 2) A more robust method is to send two bytes, first with the actual command and second with the 'not' of the first command. 3) Even better is to send a 'command coming' byte, followed by the command, followed by the compliment of the command, followed by a 'end of command byte. The 'command coming' and 'end of command' bytes should be selected to not overlay with any of the command and compliment command bytes – user3629249 Nov 09 '15 at 19:22
  • since you only need 10 commands hamming code + parity bit is a no brainer. – Vladimir Cravero Nov 09 '15 at 19:25
  • Didn't know about Hamming, thanks, that sounds really promising! – JavaForStarters Nov 09 '15 at 19:29
  • 1
    If you only need 10 commands, you can fit two copies in every byte (for redundancy), plus parity bits. Or since you have a symbol space of 256 symbols, and only need 10, you could simply choose maximally different symbols (all symbols differ by multiple bits), or choose only symbols with even numbers of ones and zeros. You certainly don't have to worry about single bit errors. – user57037 Nov 09 '15 at 21:40
  • Some decent thought has been put into formatting data in the moment, but you should also do some thinking about sequencing and messages potentially delayed due to buffering - you may not desire that, but by default you will have it on the PC end. Since you mention USB (presumably USB-connected UARTs), also think about the latency that can introduce and potential issues around (re) enumeration. – Chris Stratton Nov 10 '15 at 01:31
  • 1
    Hamming codes are of limited usefulness for UART communication, given that a glitch that comes just before the start of a packet may cause all subsequent data to be mis-framed. In general, one may as well figure that if any part of a packet is glitched, the entire packet should be considered useless. – supercat Nov 10 '15 at 01:59
  • 1
    It might be worth looking at how SECS/GEM messages are exchanged between equipment. You might be able to steal some ideas from that. They take message management and accuracy pretty seriously. –  Nov 10 '15 at 02:56

2 Answers2

2

I think you should define longer commands including probably checksum or CRC and wait for an ACK / NACK or error condition.

You can take examples from easy protocols like TFTP (RFC 1350)

Pat
  • 36
  • 1
2

For a safe communication you should consider all possible threads to your communication line. Therefore you need to define, if the system is accessable from the outside (third party systems e.g. wireless)

In generall you have to think about the following threads:

  • repetition
  • ommision
  • resequencing
  • manipulation
  • delay
  • insertion
  • corruption

Standard measures against threads are:

  • Sequencing or timestamps
  • time supervision
  • unique source and destination codes
  • response
  • identification precedure
  • some kind of checksum, hash code ...
  • cryprographic techniques some of these you already have implemented with your simple protocoll.