Skip to content

Commit

Permalink
Merge pull request #21 from Cynerd/serial-restart
Browse files Browse the repository at this point in the history
Serial restart and CAN
  • Loading branch information
fvacek authored Jan 26, 2024
2 parents 99b1f90 + 634f6ad commit 65901f7
Showing 1 changed file with 130 additions and 109 deletions.
239 changes: 130 additions & 109 deletions src/rpctransportlayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,115 +93,136 @@ message can still be consistent. The invalid message should be just dropped.
The primary transport layer is RS232 with hardware flow control, but usage with
other streams, such as TCP/IP or Unix domain named socket, is also possible.

In some cases the restart of the connection might not be available. That is for
example when application just doesn't have rights for it or even when such
restart would not be propagated to the target, for what ever reason. To solve
this the empty message is reserved (that is message `STX ETX 0x0`). Once client
receives a valid empty message then it must drop any state it keeps for it.

## CAN-FD (DRAFT)
`data` is split to N frames. There are 4 types of frame

Frame type | Value | Priority | Note
---- |---- |---- |----
SFM | 0 | 0 | Single frame message, the highest priority
MFM_START | 2 | 2 | First frame of multi frame message, higher priority than CONT
MFM_CONT | 3 | 3 | Next frame(s) of multi frame message
MFM_END | 1 | 1 | Last frame of multi frame message with CRC32

Priorities:
1. SFM has the highest priority, they should be used for notification
1. MFM_START should have higher priority than MFM_CONT to enable other client to start new session in parallel with existing session
1. MFM_CONT should have the lowest priority
1. MFM_END should have higher priority, than MFM_CONT to allow finishing session when other long message is sent.
1. MFM_END should have higher priority, than MFM_START to allow finishing session before new one is started.
1. Having these priorities we can transmit 2 frame long message (START + END) whilst other very long session is active.
1. When 2 long sessions run in parallel, then CONT messages from device with lower ID will be delivered first.

Scenarios:
1. SFM frame is lost
* receiver doesn't get message
* sender will timeout waiting for response
1. MFM_START frame is lost
* receiver will not get START message, so it cannot start session
* receiver will ignore all CONT and END messages, because there is no session SRC active
* sender will timeout waiting for response
1. MFM_CONT frame is lost
* receiver will get END message with invalid CRC
* receiver will cancel active session
* sender will timeout waiting for response
1. MFM_END frame is lost
* receiver will not get END message
* receiver will timeout and cancel active session
* sender will timeout waiting for response
1. MFM_END frame has invalid CRC
* receiver will get END message with invalid CRC
* receiver will cancel active session
* sender will timeout waiting for response
1. More senders will send MFM simultaneously to one receiver
* will receive first START message and starts receive session for sender with SRC address
* receiver will ignore all messages with senders with different SRC than one from current session
* first sender will send message
* other senders will timeout waiting for response
1. Receiver has active session and MFM_START message is received
* receiver can parse first frame and decode SHV request ID. Then it can create RPC response `device bussy` and reply with RPC Exception. This can avoid waiting till timeout on the sender side. Sender also will know that receiver is connected and alive, what is more information than the timeout can provide.

### CAN ID structure
```
+---------------+----------------+---------------------------+
| 1 bit channel | 2 bit priority | 8 bit src device address |
+---------------+----------------+---------------------------+
```
* priority
* src device address - address of sender device.

**Frames**
* `SFM` - Single frame message. SFM does not need CRC, since it is part of CAN frame already
* `MFM` - Multi frame message, consisting of `MFM_START` + `MFM_CONT`* + `MFM_END`

#### SFM
```
+---------------------------+------------------------+----------------------+
| 8 bit dest device address | 8 bit frame type (SFM) | 8 bit payload length |
+---------------------------+------------------------+----------------------+
+----------------------+
| 0 - 61 bytes payload |
+----------------------+
```

#### MFM_START
```
+---------------------------+------------------------------+
| 8 bit dest device address | 8 bit frame type (MFM_START) |
+---------------------------+------------------------------+
+------------------+
| 62 bytes payload |
+------------------+
```
Note that `MFM_START` can have only 62 bytes of payload, 61 bytes can fit to single `SFM`.

#### MFM_CONT
```
+---------------------------+-----------------------------+----------------------+----------------------+
| 8 bit dest device address | 8 bit frame type (MFM_CONT) | 8 bit payload length | 8 bit frame counter |
+---------------------------+-----------------------------+----------------------+----------------------+
+-----------------------+
| 58 - 60 bytes payload |
+-----------------------+
```
Note that `MFM_CONT` cannot have less than 58 bytes of payload, 57 bytes can fit to `MFM_END`.


#### MFM_END
```
+---------------------------+----------------------------+----------------------+
| 8 bit dest device address | 8 bit frame type (MFM_END) | 8 bit payload length |
+---------------------------+----------------------------+----------------------+
+----------------------+
| 0 - 57 bytes payload |
+----------------------+
+---------------+
| 32 bit CRC LE |
+---------------+
```
CRC32 must not be split between frames.


TODO: We need some packet that signals device overload (no ability to process new messages for some time)

## CAN-FD (DRAFT)

The communication over CAN (Control Area Network) bus. Compared to other
transport layers that are point-to-point this is bus and thus it must not only
provide message transfer but also a connection tracking.

CAN has the following abilities:
* Delivery of the CAN messages is not ensured (it can be lost)
* Single CAN message can be transmitted multiple times
* CAN messages are delivered in order based on CAN ID priority and never out of
order
* Collision is resolved by avoiding it based on the CAN ID (lower has higher
priority)
* CAN messages correctness is ensured with CRC32
* Flow control is handled by CAN overload frame

CAN bus is designed for control applications but SHV RPC is rather configuration
and management interface and thus the design here prioritizes fair queueing over
message delivery deadline guaranties. This is because we expect that SHV RPC
will overcommit the bus (contrary to common control applications).

CAN bus has limited bandwidth and thus it is not desirable in most cases to emit
all signals device has (contrary to standard SHV RPC device design). The SHV
native way to introduce filtering is to use RPC Broker and thus it is highly
suggested that devices on CAN bus should expose RPC Broker to it.

### CAN ID

CAN ID can be either 29 bits or 11 bits. SHV RPC uses exclusively only 11 bits
ID.

```
+-------------+-----------+---------+--------------------+
| NotLast [1] | First [1] | QoS [1] | Device address [8] |
+-------------+-----------+---------+--------------------+
```

* `NotLast` is `0` when no subsequent message will follow this one and `1`
otherwise. This prioritizes message termination on the bus.
* `First` is `1` when this is initial message and `0` otherwise. This penalizes
start of the new message and thus prefers SHV RPC message finish.
* `QoS` should be flipped on every SHV RPC message sent. It ensures that devices
with high CAN ID (low priority) get chance to transmit their messages. It is
allowed that device that is quiet for considerable amount of time to set it to
any state (commonly beneficial for that device).
* `Device address` this must be unique address of the device transmitting CAN
message or bitwise not of it when `QoS` is `1`. The addresses `0x0` and `0xff`
are reserved. The bit flipping of the device address based on the `QoS`
ensures that high priority CAN IDs in QoS `1` are low priority ones in the QoS
`0` and vice versa, thus devices should get somewhat equal chance to transmit
their messages.

_Note: The advantage of using only 11 bits is with CAN-FD where initial
arbitration runs in slower speed and by not using 29 bits it will be shorter and
thus communication faster._

### First data byte

The first data byte in the CAN message has special meaning.

For CAN messages with `First` bit set (`1`) in CAN ID the first byte must be
destination device address. This identifies the device this SHV RPC message is
intended for.

For CAN messages with `First` bit unset (`0`) in CAN ID the first byte must be
sequence number that starts with `0x0` for the second message (third is `0x1`
and so on). If sequence number reaches `0xff` then it just simply wraps around
to `0x0`.

The complete and valid messages thus starts with CAN message with `First` set,
continues with CAN messages where `First` is not set and `NotLast` is, and
terminates with with CAN message where `NotLast` is not set. The consistency of
the message (that no CAN message is lost) is ensured with counter in first data
byte.

Transport error is detected if CAN message with `First` not set in CAN ID is
received with byte having number out of order (while ignoring messages with
number same as the last received CAN message from that specific device). Such
SHV RPC message is silently dropped and error is ignored as subsequent messages
can be consistent again without any action.

The message can be terminated by CAN RTR message (Remote transmission request)
with both `NotLast` and `First` unset and data length set to `0x0`.

### Connection

Connection between devices is automatically established with first message being
exchanged. There can be only one connection channel between two devices. To
disengage it the special empty message can be sent (that is regular CAN message
with `NotLast` not set and `First` set in CAN ID and data containing only one
byte with destination device address.

### Broadcast

Due to the CAN bus bandwidth limitations it is suggested to expose SHV RPC
Broker instead of just plain device, but sometimes it is beneficial to not add
the signal filtering and instead to automatically broadcast signals. Such
signals are not intended for any specific device and are just submitted on the
bus with special destination device address `0xff`.

The only allowed SHV RPC message type for destination device address `0xff` is
[RpcSignal](./rpcmessage.md#rpcsignal). Other message types received with this
destination device address must be ignored and devices should not send them.

Handling of the broadcast signals is up to the application it receives it.
SHV RPC Brokers will propagate them further if given device is mounted and
subscribed.

One concrete example when this is beneficial is for date and time
synchronization device. Such device can send signals with precise time to let
other devices to synchronize with it.

### Device discovery

Devices on CAN bus must be possible to discover to not only be able to
dynamically mount them to SHV RPC Broker but also to actively diagnose the CAN
bus.

Once device is ready to receive messages on CAN bus it should send CAN RTR
message (Remote transmission request) with data length set to `0x1` (the CAN ID
should have `NotLast` not set and `First` set which applies to all CAN RTR
messages). This ensures that it gets discovered as soon as possible.

Device that wants to perform discovery can send CAN RTR message (Remote
transmission request) with data length set to `0x2`. Device that receives this
CAN message must respond with CAN RTR message with data length set to `0x1`.

0 comments on commit 65901f7

Please sign in to comment.