Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[flake8]
ignore = E203, W503
max-line-length = 88

# Necessary for compatibility with the Black formatter.
ignore = E203, W503
14 changes: 7 additions & 7 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"

- uses: actions/cache@v2
- uses: actions/cache@v4
with:
path: ~/.local
key: poetry-1.2.2
key: poetry-1.8.0

- uses: snok/install-poetry@v1
with:
version: 1.2.2
version: 1.8.0
virtualenvs-create: true
virtualenvs-in-project: true

- uses: actions/cache@v2
- uses: actions/cache@v4
id: cache-deps
with:
path: .venv
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"

- uses: actions/cache@v2
- uses: actions/cache@v4
with:
path: ~/.local
key: poetry-1.2.2
key: poetry-1.8.0

- uses: snok/install-poetry@v1
with:
version: 1.2.2
version: 1.8.0
virtualenvs-create: true
virtualenvs-in-project: true

- uses: actions/cache@v2
- uses: actions/cache@v4
id: cache-deps
with:
path: .venv
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
__pycache__/
.history
.mypy_cache/
.pytest_cache/
.vscode/
Expand Down
17 changes: 15 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
# Changelog

## Unreleased

Highlights:
* Added: support for asynchronous handles.
* Added: escaping of the header and body (protocol).
* Changed: minimal Python version is Python 3.12.
* Changed: body checksum is always included (protocol).
* Changed: body checksum is now calculated over header and payload (protocol).
* Fixed: preamble is now read as string of bytes.
* Improved: CLI is more interactive.
* Improved: consistent terminology and naming.
* Removed: reserved flags (protocol).

## v2.0.0
Released 17 September 2015

Highlights:
* Added: Python 3.4 support.
* Improved: More strict handling of bytes.
* Improved: Formatted code according to PEP8.
* Improved: more strict handling of bytes.
* Improved: formatted code according to PEP8.
* Changed: ResetFrame is now a Frame, with correct flags set.
* Changed: DamagedFrame is now a property on a Frame.

Expand Down
31 changes: 14 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,26 @@ streaming protocol for low-speed embedded applications, such as serial
connected devices. It allowes the receiver to 'jump into' a stream of data
frames. Every frame starts with a preamble, so the receiver can synchronize.

A payload is optional.

The format of a frame is as follows:

```
| Preamble | Header | Body |
| 0xAA 0x55 0xAA 0x55 | AA AA BB BB CC | XX XX .. .. .. .. XX XX YY YY YY YY |
| Preamble | Header | Body (optional) |

Fields:
A = Length
B = Flags
A = Flags
B = Length
C = XOR checksum over header
X = Body payload (max. 65536 bytes)
Y = CRC32 checksum over header + body
X = Payload (max. 65536 bytes)
Y = CRC32 checksum over header + payload
```

The flags field can have arbitrary values, but the following flags are
reserved.
The flags field can be used for arbitrary purposes. The payload is optional.

* `0x01 = RESET`
* `0x02 = ERROR`
* `0x04 = PRIORITY`
Escaping of the header and body are performed using byte-stuffing, to ensure
that the header and body can contain bytes of the preamble.

Error correction is not implemented and the bytes are not aligned. The
Error correction is not implemented and the bytes are not strictly aligned. The
endianness is customizable.

## State chart diagram
Expand All @@ -45,15 +41,16 @@ The latest development version can be installed via
`pip install git+https://github.com/basilfx/python-tinylink`.

## CLI
A simple serial CLI is included. When installed, run
A CLI is included to experiment with TinyLink. When installed, run
`tinylink /dev/tty.PORT_HERE` to start it. You can use it to send raw bytes via
the link and display what comes back.

The CLI supports so-called modifiers to modify the outgoing data. For example,
the input `\flags=1 hello world` would send a reset frame with the value
'hello world'.
the input `\flags=16 hello world` would send a frame with the flags equal to 16
and the payload 'hello world'

PySerial is required to run this CLI.
The CLI requires additional dependencies, that are installed using the `cli`
dependency specification (`poetry install --extras cli`).

## Tests
To run the tests, please clone this repository and run `poetry run pytest`.
Expand Down
12 changes: 4 additions & 8 deletions docs/statechart.dot
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@ digraph G {
receiving_header[shape=box, style=rounded, label="Receiving\nheader"]
receiving_body[shape=box, style=rounded, label="Receiving\nbody"]

output_reset_frame[shape=box, style=rounded, label="Output\nreset frame"]
output_data_frame[shape=box, style=rounded, label="Output\ndata frame"]
output_frame[shape=box, style=rounded, label="Output frame"]

start -> waiting_for_preamble

waiting_for_preamble -> waiting_for_preamble[label="Byte received"]
waiting_for_preamble -> receiving_header[label="Preamble detected"]

receiving_header -> receiving_header[label="Byte received"]
receiving_header -> receiving_body[label="Header complete,\nbody expected"]
receiving_header -> receiving_body[label="Header complete,\nchecksum OK"]
receiving_header -> waiting_for_preamble[label="Header invalid"]

receiving_header -> output_reset_frame[label="Header complete,\nreset frame"]
output_reset_frame -> waiting_for_preamble

receiving_body -> receiving_body[label="Byte received"]
receiving_body -> waiting_for_preamble[label="Body invalid"]

receiving_body -> output_data_frame[label="Body complete,\ndata frame"]
output_data_frame -> waiting_for_preamble
receiving_body -> output_frame[label="Body complete,\nchecksum OK"]
output_frame -> waiting_for_preamble
}
Binary file modified docs/statechart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading