MUDL lets us promote any Serial port (UART) into a competent link / transport layer with guaranteed delivery of framed packets.

I’ve posted about this link layer here and made it available as an arduino library in the manager.

mudl

We use a simple statemachine, not dissimilar from TCP’s strategies.

statemachine

MUDLink ingests any Serial instance within the Arduino ecosystem, meaning it can be deployed in just about any Arduino project. We instantiate it using a a template like this:

// 2nd argument is the baudrate 
MUDL_Link<decltype(Serial1)> mudl(&Serial1, 2000000);

It has a pretty simple API, we can check if the link is clear to send or clear to read, and we can send and read packets.


uint8_t appRx[255];
uint8_t appTx[255]; 

void loop(void){
  // MUDLink runs on an event loop, 
  mudl.loop();

  // check-then-read,
  if(mudl.clearToRead()){
    mudl.read(appRx, 255);
  }
  
  // presuming we have stuffd appTx with a message: 
  if(mudl.clearToSend()){
    mudl.send(appTx, msgLen);
  }

  // and we can get those stats, 
  MUDLStats stats = mudl.getStats(); 
}

The message spec is pretty simple as well, beneath our COBS encoded packets we have this block:

Bytes 0 … N-5 Byte Len-4 Byte Len-3 Byte Len-2 Byte Len-1
… Payload ACKD_SEQ TXD_SEQ CRC:1 CRC:2

So, pretty small overhead, and the payload is simply missing when we send ack-only or keepalive messages.