|
|
|
@ -2,22 +2,33 @@ |
|
|
|
|
|
|
|
|
|
TinyFrame is a simple library for building and parsing frames to be sent |
|
|
|
|
over a serial interface (e.g. UART, telnet etc.). The code is written |
|
|
|
|
in `--std=gnu89`. |
|
|
|
|
to build with `--std=gnu89` and later. |
|
|
|
|
|
|
|
|
|
Frames are protected by a checksum (~XOR, CRC16 or CRC32) and contain |
|
|
|
|
a unique ID field, which can be used for chaining messages. The highest value |
|
|
|
|
of the ID is different for each peer (TF_MASTER or TF_SLAVE) to avoid collisions. |
|
|
|
|
TinyFrame is suitable for a wide range of applications, including inter-microcontroller |
|
|
|
|
communication, as a protocol for FTDI-based PC applications or for messaging through |
|
|
|
|
UDP packets. If you find a good use for it, please let me know so I can add it here! |
|
|
|
|
|
|
|
|
|
All fields in the frame have configurable size (see the top of the header file). |
|
|
|
|
By just changing a value, like `TF_LEN_BYTES`, the library seamlessly switches |
|
|
|
|
from `uint8_t` to `uint16_t` or `uint32_t` to support longer payloads. |
|
|
|
|
Frames can be protected by a checksum (~XOR, CRC16 or CRC32) and contain |
|
|
|
|
a unique ID field which is be used for chaining related messages. The highest bit |
|
|
|
|
of the generated IDs is different for each peer to avoid collisions. |
|
|
|
|
Peers are functionally equivalent and can send messages to each other |
|
|
|
|
(the names "master" and "slave" are used only for convenience). |
|
|
|
|
|
|
|
|
|
The library lets you bind listeners waiting for any frame, a particular frame Type, |
|
|
|
|
or a specific message ID. This lets you easily implement asynchronous |
|
|
|
|
The library lets you register listeners (callback functions) to wait for (1) any frame, (2) |
|
|
|
|
a particular frame Type, or (3) a specific message ID. This lets you easily implement asynchronous |
|
|
|
|
communication. |
|
|
|
|
|
|
|
|
|
## Frame structure |
|
|
|
|
|
|
|
|
|
All fields in the message frame have a configurable size (see the top of the header file). |
|
|
|
|
By just changing a definition in the header, such as `TF_LEN_BYTES` (1, 2 or 4), the library |
|
|
|
|
seamlessly switches between `uint8_t`, `uint16_t` and `uint32_t`. Choose field lengths that |
|
|
|
|
best suit your application needs. |
|
|
|
|
|
|
|
|
|
For example, you don't need 4 bytes (`uint32_t`) for the |
|
|
|
|
length field if your payloads are 20 bytes long, using a 1-byte field (`uint8_t`) will save |
|
|
|
|
3 bytes. This may be significant if you high throughput. |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
,-----+----+-----+------+------------+- - - -+------------, |
|
|
|
|
| SOF | ID | LEN | TYPE | HEAD_CKSUM | DATA | PLD_CKSUM | |
|
|
|
@ -35,8 +46,9 @@ DATA_CKSUM .. checksum, implemented as XOR of all preceding bytes in the message |
|
|
|
|
|
|
|
|
|
## Usage Hints |
|
|
|
|
|
|
|
|
|
- Both peers must include the library with the same parameters (config in the header file) |
|
|
|
|
- Start by calling `TF_Init()` with MASTER or SLAVE as the argument |
|
|
|
|
- All TinyFrame functions, typedefs and macros start with the `TF_` prefix. |
|
|
|
|
- Both peers must include the library with the same parameters (configured at the top of the header file) |
|
|
|
|
- Start by calling `TF_Init()` with `TF_MASTER` or `TF_SLAVE` as the argument |
|
|
|
|
- Implement `TF_WriteImpl()` - declared at the bottom of the header file as `extern`. |
|
|
|
|
This function is used by `TF_Send()` to write bytes to your UART (or other physical layer). |
|
|
|
|
Presently, always a full frame is sent to this function. |
|
|
|
|