4

I want to interface two microcontrollers with a UART interface and I search a protocol to exchange data between them.

In practice, I want to exchange data periodically (ie: sensors reading) and also data on event (GPIO state). I have around 100-200 bytes to exchange every 100 milli second.

Does anybody know a protocol or library to achieve this kind of task ?

For now, I see protobuf and nano protobuff ? Is there something else ? It would be nice if I could add a software layer over the UART and use "virtual data stream" like if it was a TCP/IP connection to N ports.

Any idea ? Thanks

ssinfod
  • 975
  • 2
  • 15
  • 31

5 Answers5

6

I think the most straight forward way is to roll your own.

You'll find RS232 drivers in the manufacturers chip support library.

RS232 is a stream oriented transport, that means you will need to encode your messages into some frameing structure when you send them and detect frame boundaries on the receiver side. A clever and easy to use mechanism to do this is "Consistent Overhead Byte Stuffing".

https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing

This simple algorithm turns zeros in your messages into some other value, so the zero-byte can be used to detect start and end of frame. If a byte gets corrupted on the way you can even resynchronize to the stream and keep going.

The code on Wikipedia should be easy enough even for the smallest micro-processors.

Afterwards you can define your message format. You can probably keep it very simple and directly send your data-structures as is.

Suggestion for a simple message format:

Byte-ID   Meaning
---------------------------------
0         Destination port number
1         message type (define your own)
2 to n    message data

If you want to send variable length messages you can either send out a length byte or derive the length from the output of the Constant Overhead Byte Stuffing framing.

By the way, UART/RS232 is nice and easy to work with, but you may also want to take a look at SPI. The SPI interface is more suitable to exchange data between two micro-controllers. It is usually faster than RS232 and more robust because it has a dedicated clock-line.

harper
  • 13,345
  • 8
  • 56
  • 105
Nils Pipenbrinck
  • 83,631
  • 31
  • 151
  • 221
4

How about this: eRPC https://community.nxp.com/docs/DOC-334083

The eRPC (Embedded Remote Procedure Call) is a Remote Procedure Call (RPC) system created by NXP. An RPC is a mechanism used to invoke a software routine on a remote system using a simple local function call. The remote system may be any CPU connected by an arbitrary communications channel: a server across a network, another CPU core in a multicore system, and so on. To the client, it is just like calling a function in a library built into the application. The only difference is any latency or unreliability introduced by the communications channel.

I have use it in a two processor embedded system, a cortext-A9 CPU with a Context-M4 MCU, which communicate each other with SPI/GPIO.

Erpc can run over UART, SPI, rpmsg and network(tcp). even when using serial or SPI as transport tunnel, it can do bidirectional calls and with very minimal footprint.

redice li
  • 106
  • 2
1

Simple serial point-to-point communication protocol

http://www.zipplet.co.uk/index.php/content/openformats_mise

It depends if you need master/slave implementation, noise protection, point-point or multi-point (and in this case collision detection), etc

but, as our colleague said, I would go with the simplest solution that fits the problem, following the KISS principle http://en.wikipedia.org/wiki/KISS_principle

Just add some header information like ID and length, if necessary CRC checking, and be happy :)

Community
  • 1
  • 1
Gustavo Laureano
  • 556
  • 2
  • 10
1

Try Microcontroller Interconnect Network (MIN) 1.0:

https://github.com/min-protocol/min

It has framing using byte-stuffing to keep receiver sync, 16-bit Fletcher's algorithm for checksum, an identifier for use by the application and a variable payload of up to 15 bytes.

There's embedded C code there plus also a Python implementation to make it easier to talk to a PC.

Ken Tindell
  • 343
  • 4
  • 7
0

As the first answer starts, the simplest result is to roll your own. Define your header (the "format" above) as needed, perhaps including status information so each processor knows that the other is working properly. I have had success with a protocol that includes

  1. 2 byte ascii prefix and suffix such as "[" and "]" so that a protocol analyzer can show you message boundaries.
  2. The number of bytes.
  3. The command ID (parsed to indicate what command handler to use.
  4. Command arguments (I used 3 32 bit words).
  5. A CRC or checksum to verify transfer integrity

The parser then recognizes the [* as the start of the message, and dispatches the body to the command handler for the particular command ID with the associated arguments as long as the checksum matches.

Bruce
  • 2,230
  • 18
  • 34