UART Datagram Composition
This guide explains the both transport and link layers for UART datagrams used by the YOS communication system 'umsg'. The transport layer determines the datagram byte ordering, redundancy checks and start/end of frame recognition mechanisms. The link layer defines the device addressing and sevice identification. The umsg link layer omits the sender address due to the implicit 1:n topology. The construct can be used for the utility driver and common I/O API communication.
UART Frame Structure
Byte | Description |
---|---|
0 | session | 0x80 |
1 | (session | 0x80)^UMSG_VERSION |
2 | Message length - 1 |
3 | Paylaod byte 0 (SID - link layer) |
4 | Payload byte 1 (Receiver address - link layer) |
5 | Payload byte 0 |
6 | Payload byte 1 |
7 | Payload byte 2 |
5 + n | Payload byte n |
Last byte | CRC |
CRC Calculation
CRC is calculated by XORing all bytes in the UART message, excluding the first two bytes.
crc = Byte2 ^ Byte3 ^ Byte4 ^ ... ^ Last_byte
Session increment
The sender must increment the session number each time a new datagram is composed. If the receiver gets multiple times a message with the same session, it is discarded.
UART Frame Creation Example (C Code)
/*!
\brief Create the UART frame (umsg)
\param[in] payload_len - Number of bytes to send
\param[in] payload - payload to send
0 byte of data = SID
1 byte of data = Receiver addr
2-end bytes = Payload
\param[in] output_buf - Output buffer
\param[in] output_buf_len - Number of bytes in output buffer
\return int32_t
0 - success
-1 - output (tx) buffer too small
*/
#define UMSG_VERSION 0x55
int32_t
umsg_compose_datagram(uint8_t payload_len, const uint8_t* payload, uint8_t* output_buf, uint8_t output_buf_len)
{
static uint8_t session = 0;
if (payload_len + 4 > output_buf_len)
return -1;
session |= 0x80;
*output_buf++ = session;
*output_buf++ = session ^ UMSG_VERSION;
*output_buf++ = payload_len - 1;
uint8_t crc = 0;
crc ^= payload_len - 1;
for (int i = 0; i < payload_len; i++) {
crc ^= *payload;
*output_buf++ = *payload++;
}
*output_buf++ = crc;
session++;
return 0;
}