===================== Protocol AVR module ===================== :Author: Nicolas Schodet Introduction ============ This module handles a communication protocol suitable to be used with a serial line. It handles coding and decoding. To use the decoding part, just call a dedicated function at each character reception. If a complete frame has been received, the callback defined by the user is called with the received frame as parameter. The encoding part is a set of functions to send frames with a given format. Protocol ======== The protocol is based on frames composed of readable characters. This permits easy debugging for human eyes. Each frame starts with an exclamation mark (``!``) and stops with a carriage return (``\r``). Any extra character not embedded in a frame is ignored. The exclamation mark is directly followed by the command character. This is an alphabetic character, lower or upper case. After the command comes a list of arguments. Arguments are coded in pairs of hexadecimal digits. Each pair corresponds to one byte. Several bytes can be combined to form words or double words, but this is not represented in the protocol, there are simply concatenated. For example:: !z !v03f5 !c0094ffa8 A printable ASCII character can also be sent directly using a simple quote (``'``), this is equivalent to send the ASCII code as a pair of hexadecimal digits. For example, theses two frames are equivalents:: !p's40 !p7340 Last, a string of printable characters can be sent using a double quote (``"``):: !p"Hello World Warning: the exclamation mark is still a special character. Theses two modes are provided for human interaction. If a program needs to send a character string, it should rather send them as hexadecimal arguments. Error checking ============== This module does not enforce any error checking, but here is a proposed system: - For reliable messages, the slave device must sent back the received command as acknowledgement once it has been handled. - For unreliable messages, there is no acknowledgement. - If the slave device does not understand a message from the master device, it sends a frame with the ``?`` command to signal the error in order to shorten retransmission delay. A unreliable message is a message which is sent regularly and for which a retransmission would not be interesting as we prefer to wait for the next newer value than retransmit the old one. Only the slave device sends acknowledgement or error messages. The upper layer protocol should take this into account during the design phase. Pitfalls ======== Using the error checking procedure defined above, there is some pitfalls if the master is not a human: Handling duplicates ------------------- If the slave device received the message, but its acknowledgement was not received by the master, the master can retransmit the frame. This behaviour can leads to duplicate receptions of frames. If this causes a problem for your application, you should add a mechanism, like a sequence number, in order to detect duplicates. For example, include an extra sequence number at the end of your frame. When the slave receives the frame, it first checks that this sequence number is not the last received one. If it matches, the frame is ignored, but an acknowledgement is sent anyway. If it does not match, the frame is handled, the sequence number is remembered and an acknowledgement is sent. This sequence number can also be used by the slave to signal that a long command is finished. Unexpected transmission from the slave -------------------------------------- There is no acknowledgement from the master and no retransmission from the slave. Therefore, the slave is not able to know if its message has been received. To handle this, here is two methods: - Transmit periodically a variable which must be known by the master instead of sending only changes. - Transmit periodically a sequence number once an event occurs. The master must give this sequence number back to stop the transmission. Usage ===== The user must define a callback function to handle incoming frames, and a function used to send a character. The names of theses function is defined in ``avrconfig.h``. For each received character, the function ``proto_accept`` should be called. To send frames, the ``proto_send...`` functions should be used. API === .. include:: proto.exd