I want to design a very simple, efficient protocol layer, point-to-point, that uses a UART on a low-end 8-bit microprocessor. It has extremely limited RAM, and only the most simple arithmetic operations. The UART handles framing of bytes, and it can be assumed that this layer can rely on this fact. (error detection will be done on a higher level).
The protocol would work as follows:
- Server and client are indistinguishable
- Receiving and transmission are done completely independently (so only one-way need be considered)
- Connectionless and unreliable (a frame/packet will be sent-and-forgotten)
- A frame/packet will be delimited with a start, so requiring as little RAM as possible (in the order of a few bytes) while detecting the start of a frame.
- A frame/packet will be delimited with an end, to distinguish between 1. a delay in reception of the next byte and 2. the end of the frame/packet.
My first idea was as follows:
- The start of a frame consists of a byte:
00xxxxxx
(wherex
can be used for specifying the type of frame for the higher level) - The end of a frame consists of a byte:
11xxxxxx
(wherex
is discarded) - The frame contains any number of content bytes:
01xxxxxx
(wherex
is content)
This would mean the microprocessor literally doesn't need any RAM whatsoever while waiting for the start of a frame; it only has to check each byte as it's received to see if it matches 00xxxxxx
.
The problem with this idea is obviously it's wasteful of bandwidth: 2 of every 8 bits (plus the whole of the end-delimiting byte).
My second, flawed idea was to do something similar with, say, two bytes instead of one. For example:
- The start of a frame consists of one byte as above:
00xxxxxx
- The end of a frame would also be one byte also as above:
11xxxxxx
- The content would be in pairs of bytes:
01xxxxxx
,xxxxxxxx
But this is flawed because the second byte of a content byte-pair could be confused with either a start or an end delimiter. The UARTs could be disconnected and reconnected at any time without warning, so there needs to be a way for this layer to find the beginning of a packet through the values of bytes.
My logic is failing - I can't see a way of improving on my first version. I've been reading up on loads of different protocols and I can't find any that I could adapt, let alone use as-is. Is my second idea fatally flawed? Or have I just not realised how a start delimiter could be distinguished from that of the second content byte, without storing too much in RAM?
Any ideas welcome, including protocols that I could adapt or adopt, or changes to the above ideas.
Response to comments
UDP seems very much like overkill, and is too high level. I certainly don't need addressing (ports or otherwise). I don't think the OSI model can be applied to my requirements, but I need something more at the data link layer rather than transport later (UDP). It will be (a part of a re-usable stack) for communication between a host (usually a PC) and a microprocessor (PIC, Atmel) via a virtual COM (serial) port (Using bluetooth-UART or USB-UART hardware bridges). It will by no means be a one-size-fits-all protocol, but just something which suits very limited hardware capabilities for tasks such as sending key+value pairs, or command+parameters etc, where the values/parameters will be of variable length, anywhere from 0 to over 2^16 (but could be split up). Some protocols that come close but are also overkill:
The greatest priority is low computational requirements and resources, followed by bandwidth efficiency.
The microprocessors will invariably either use data as it's being received, or send data as it's acquired, which is why they won't have much RAM. They might also do real-time processing so the less they need to manipulate data for transmission/reception, the better. The reason low end microprocessors are being used is because there will be a lot of them, and costs will need to be kept down.