Skip to content

Serial protocol

Raido Pahtma edited this page Jul 17, 2015 · 10 revisions

Abstract

This page describes the serial protocol(with possible modifications and additions) derived from the TinyOS HDLC-like protocol. Most of this can be derived from TEP113(http://www.tinyos.net/teps/doc/html/tep113.html), however some of the information there does not reflect the actual implementation.

Packets

There are 3 types of packets currently defined: acknowledged packets(ackpacket), acknowledgement packets(ack) and unacknowledged packets(noackpacket).

Acknowledged packets (ackpackets)

Raw data

__________________________________
| | | | |                   |  | |
|_|_|_|_|___________________|__|_|
 F P S D      Payload        CR F

F       = Framing byte, denoting start of packet: 0x7E
P       = Protocol byte: 0x44
S       = Sequence number byte: 0x00-0xFF
D       = Packet format dispatch byte: 0x00-0xFE
Payload = Data payload
CR      = Two-byte CRC from P to end of payload (Little-endian)
F       = Framing byte denoting end of packet: 0x7E

Examples

(1) 7E 44 00 FF 9D DF 7E
(2) 7E 44 00 0E 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 3B 8B 7E
(3) 7E 44 00 0E 7D 5E 7D 5E 7D 5E ED B9 7E (actual payload is 7E 7E 7E)
(4) 7E 44 00 0E 7D 5D 7D 5E 33 62 7E (actual payload is 7D 7E)

Dispatcher ID=0 ActiveMessage

______________________________________________
| | | | |  |  | | | |                   |  | |
|_|_|_|_|__|__|_|_|_|___________________|__|_|
 F P S D DD SS L G A    Payload          CR F

F       = Framing byte, denoting start of packet: 0x7E
P       = Protocol byte: 0x44
S       = Sequence number byte: 0x00-0xFF
D       = Packet format dispatch byte: 0x00
DD      = Destination (Big-endian): 0x0000-0xFFFF
SS      = Source (Big-endian): 0x0000-0xFFFF
L       = Payload length
G       = AM group: 0x00-0xFF
A       = AM ID: 0x00-0xFF
Payload = Data payload
CR      = Two-byte CRC from P to end of payload (Little-endian)
F       = Framing byte denoting end of packet: 0x7E

Examples

(1) 7E 44 00 00 FF FF 00 01 00 22 00 D1 38 7E
(2) 7E 44 00 00 FF FF 00 01 05 22 AA 01 02 03 04 05 E8 7D 5D 7E (CRC with escaped byte)
(3) 7E 44 00 00 FF FF BE EF 05 22 AA 01 02 03 04 05 53 39 7E

Acknowledgements (acks)

____________
| | | |  | |
|_|_|_|__|_|
 F P S CR F

F       = Framing byte, denoting start of packet: 0x7E
P       = Protocol byte: 0x43
S       = Sequence number byte: 0x00-0xFF
CR      = Two-byte CRC from P to end of payload (Little-endian)
F       = Framing byte denoting end of packet: 0x7E

Examples

(1) 7E 43 27 1A 0C 7E

Unacknowledged packets (noackpacket)

Raw data

________________________________
| | | |                   |  | |
|_|_|_|___________________|__|_|
 F P D    Payload          CR F

F       = Framing byte, denoting start of packet: 0x7E
P       = Protocol byte: 0x45
D       = Packet format dispatch byte: 0x00-0xFE
Payload = Data payload
CR      = Two-byte CRC from P to end of payload (Little-endian)
F       = Framing byte denoting end of packet: 0x7E

Examples

(1) 7E 45 80 00 01 21 19 0F 15 00 00 D6 00 00 00 1E 21 6C 7E

Dispatcher ID=0 ActiveMessage

____________________________________________
| | | |  |  | | | |                   |  | |
|_|_|_|__|__|_|_|_|___________________|__|_|
 F P D DD SS L G A    Payload          CR F

F       = Framing byte, denoting start of packet: 0x7E
P       = Protocol byte: 0x45
D       = Packet format dispatch byte: 0x00
DD      = Destination (Big-endian): 0x0000
SS      = Source (Big-endian): 0x0000
L       = Payload length
G       = AM group: 0x00
A       = AM ID: 0xEA
Payload = Data payload
CR      = Two-byte CRC from P to end of payload (Little-endian)
F       = Framing byte denoting end of packet: 0x7E

Examples

(1) 7E 45 00 FF FF 00 00 02 00 88 00 03 B2 33 7E

Packet format dispatch byte

The first byte of the packet is the packet format dispatch byte(dispatcher ID). This is used to determine the contents of the packet. The most common use case is to transport (Serial)ActiveMessage packets over a serial link. ActiveMessage packets have the dispatcher ID 0. TinyOS additionally defines dispatcher identifiers 1, 2 and FF. Other values can be used to multiplex additional protocols.

HDLC framing and escaping

0x7E is not allowed to occur inside the frame since it marks the start and end of the frame. 0x7D is used as an escape byte and the original 0x7E is XORed with 0x20. The same applies to any 0x7D bytes inside the frame. So 0x7E and 0x7D are sent as 2 bytes. Replacements are done after the calculation of the CRC and 0x7D and 0x7E bytes in the CRC are also escaped.

0x7E -> 0x7D 0x5E
0x7D -> 0x7D 0x5D

Current implementations always frame a packet on both ends, but the receiver must also be able to properly receive packets, if only a single 0x7E is sent between two packets and also if an arbitrary number of 0x7E bytes are sent between packets.

CRC

The CRC is an ITU-T G_16 CRC with the polynomial G_16(x) = x^16 + x^12 + x^5 + 1. The value is sent as Little-endian.

uint16_t calculateCrc(const uint8_t ptr[], uint8_t length) {
    uint8_t i;
    uint16_t crc = 0;
    while(length-- > 0) {
        crc = crc ^ *ptr++ << 8;
        i = 8;
        do {
            if (crc & 0x8000) crc = crc << 1 ^ 0x1021;
            else crc = crc << 1;
        }
        while(--i);
    }
    return crc;
}

Default configuration

In the default configuration PC sends acknowledged packets and waits for an acknowledgement from the device. If an acknowledgement is not received in (implementation specific?) milliseconds, the PC repeats the packet 3? times. In the default configuration the embedded device sends noackpackets.

Serial connection baud rate is 115200 and character configuration is 8N1 (8 data bits, no parity, 1 stop bit).

The original TinyOS serial component does not implement support for receiving noackpackets, which get silently dropped(this is an unfortunate shortcoming and will hopefully get fixed at some point). It also does not support sending ackpackets.

(SerialForwarder support for receiving ackpackets needs to be verified).