summaryrefslogtreecommitdiffhomepage
path: root/digital/avr/modules/proto/proto.txt
blob: fbf1322f0ecfb95027774bd5ef8507be72a4fb64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
=====================
 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