Error
correction
The
most common way to deal with transmission errors is that the receiver
asks the sender to re-send the message. Under normal circumstances
error rate i slow and the message will be correctly received on the
second attempt. In any case there will be some limit on the number of
retries (and timeout waiting for a message re-send).
For
the sender to know when the message is received and thus no re-send
will be necessary the receiver needs to acknowledge the message so the
sender can let go of the message and proceed to the next message.
Basically there are two outcomes - ACK meaning i twent OK and receiver
is ready for next message, or NAK meaning something went wrong. In the
event of a NAK the sender needs handle the situation either by
re-sending the message or to just report the incident.
To
structure the protocol stack we should take care of error correction in
a dedicated layer, thus we must be able to distinguish data packets
from ACK/NAK packets, e.g. like this:
Sent:
TYPE_DATA |
data |
crc |
framing |
Receved:
TYPE_ACK |
ack data |
crc |
framing |
One obvious way is to use the START as
start of a data package and another dedicated code for ACK
packages.
An
extension is to have a third type of packet that does not use error
correction (no ACK is expected in return). Maybe even a type of package
that doesn't transmit crc, e.g. if receiver can still use the message
despite errors, like an audio channel.
All this costs some codes though
increasing the number of codes that can not be transmitted in its raw
form.
The
crc could as well be transmitted at start of message. It is natural to
have it in the end since this is where we compare computed crc with
sender's supplied crc.
If we only
have a unidirectional channel the receiver must be able to correct
errors in the message without being able to ask for re-send. This can
also be the case if turn-around time is unacceptably long, e.g. when
streaming real time data like audio or video. An extreme is
sending a command to a Mars vehicle - with two hours transmit speed in
each direction you wouldn't want a resend request 4 hours later but
rather send every command 10 times or so to be reasonably confident at
least one of them got through.
Error
correcting codes are complex
but pretty standard, implemented on every hard disk to reduce
irreparable surface errors. But usually in an embedded system it is
cheaper to manage with resend requests.
An
easy (though not optimal) forward error correcting scheme is to send an
(up to) 8 byte block, then two more bytes with horizontal and vertical
parity bits.
1 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
|
Grey digits are (even) parity. If the parity is wrong in one row and
one column we can pinpoint which bit is in error. If only one bit is
wrong we assume it is the parity bit, but it could of course be a
multi-bit error. With 9 bit transfers this scheme is trivial and you
get an extra bit (unfilled corner above) indicating error in parity.
Next
>
|