40

After writing several different custom serial protocols for various projects, I've started to become frustrated with re-inventing the wheel every time. In lieu of continuing to develop custom solutions for every project, I've been searching for a more general solution. I was wondering if anyone knows of a serial protocol (or better yet, implementation) that meets the following requirements:

  • Support multiple devices. We'd like to be able to support an RS485 bus.
  • Guaranteed delivery. Some sort of acknowledgement mechanism, and some simple error detection (CRC16 is probably fine).
  • Not master/slave. Ideally the slave(s) would be able to send data asynchronously. This is mostly just for aesthetic reasons, the concept of polling each slave doesn't feel right to me.
  • OS independence. Ideally it wouldn't rely on a preemptive multitasking environment at all. I'm willing to concede this if I can get the other stuff.
  • ANSI C. We need to be able to compile it for several different architectures.

Speed isn't too much of an issue, we're willing to give up some speed in order to meet some of those other needs. We would, however, like to minimize the amount of required resources.

I'm about to start implementing a sliding window protocol with piggybacked ACKs and without selective repeat, but thought that perhaps someone could save me the trouble. Does anyone know of an existing project that I could leverage? Or perhaps a better strategy?

UPDATE
I have seriously considered a TCP/IP implementation, but was really hoping for something more lightweight. Many of the features of TCP/IP are overkill for what I'm trying to do. I'm willing to accept (begrudgingly) that perhaps the features I want just aren't included in lighter protocols.

UPDATE 2
Thanks for the tips on CAN. I have looked at it in the past and will probably use it in the future. I'd really like the library to handle the acknowledgements, buffering, retries etc, though. I guess I'm more looking for a network/transport layer instead of a datalink/physical layer.

UPDATE 3
So it sounds like the state of the art in this area is:

  • A trimmed down TCP/IP stack. Probably starting with something like lwIP or uIP.
  • A CAN based implementation, it would probably rely heavily on the CAN bus, so it wouldn't be useful on other physical layers. Something like CAN Festival could help along the way.
  • An HDLC or SDLC implementation (like this one). This is probably the route we'll take.

Please feel free to post more answers if you come across this question.

dsolimano
  • 8,870
  • 3
  • 48
  • 63
Gabe
  • 2,526
  • 1
  • 23
  • 24
  • Yup, I've seen that one before, also this one: http://stackoverflow.com/questions/815758/simple-serial-point-to-point-communication-protocol Both focus on a relatively simple protocol. I'm looking for something considerably more robust and fully featured. – Gabe Jul 21 '09 at 14:08
  • Here are a couple similar questions to get you started. You have more requirements than those who asked the other questions. http://stackoverflow.com/questions/815758/simple-serial-point-to-point-communication-protocol http://stackoverflow.com/questions/310826/protocols-used-to-talk-between-an-embedded-cpu-and-a-pc – dwhall Jul 21 '09 at 14:09
  • @ChrisW strongly considered it, I'd really like something lighter weight. – Gabe Jul 21 '09 at 14:21
  • OSHDLC moved to https://github.com/dipman/OSHDLC – Leonardo Santagada Jul 17 '14 at 02:52
  • I'm relatively new to embedded development and I'm a bit astonished by the lack of a good serial protocol with the basic features as outlined in this question. Basically I'm looking for something on the basic serial RS232 which has some form of error control and hence of guaranteed delivery, say go-back-n or selective repeat, with byte stuffing and the rest. The question was lastly edited in 2012, now in 2017 I'd like to ask Gabe what is the end of the story, i.e. what solution they finally adopted and if in the meantime some other open source project started addressing this topic. – Federico Strati Mar 10 '17 at 09:17

6 Answers6

12

Have you considered HDLC or SDLC?

There's also LAP/D (Link Access Protocol, D-Channel).

Uyless Black's "Data Link Protocols" is always nearby on my bookshelf - you might find some useful material in there too (even peruse the TOC & research the different protocols)

Dan
  • 10,303
  • 5
  • 36
  • 53
5

I'd guess a reasonable starting point could be uIP.

(Adding Wikipedia article on µIP since original link is dead.)

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Javier
  • 60,510
  • 8
  • 78
  • 126
  • love it, that's exactly the kind of thing I'm looking for – Gabe Jul 21 '09 at 14:31
  • Like I said to ChrisW, though, I'd love to go lighter (if something exists). I suppose I could always use uIP as a starting point and just start stripping stuff out though. – Gabe Jul 21 '09 at 14:44
  • according to the page, it's quite modular; so you could use just the IP layer and get rid of TCP, UDP and everything above it – Javier Jul 21 '09 at 15:23
  • Normally you'd want to use PPP for transporting IP over a serial link, but that doesn't do multi-drop. What transport layer protocol would you put IP onto for a multi-drop RS-485? – Craig McQueen Jul 22 '09 at 00:39
  • topologically, rs-485 is similar to old coaxial ethernet. either wrap the packets on some small frame (with some mac-like id), or just drop them naked on the wire and have the IP layer reject the packets that aren't for you. – Javier Jul 22 '09 at 02:50
  • PPP was added to simple serial links to get rid of zeros while not transferring (electrically undesirable for long-haul voltage-level-triggered links), and also to add some 'connection setup' step that the telcos wanted to charge by the connection second. naked packets are much harder to bill. – Javier Jul 22 '09 at 02:52
  • 3
    @Javier link is dead – Overdrivr Feb 10 '16 at 08:12
5

CAN meets a number of your criteria:

  • Support multiple devices: It supports a large number of devices on one bus. It's not, however, compatible with RS485.
  • Guaranteed delivery: The physical layer uses bit-stuffing and a CRC, all of which are implemented in hardware on an increasing number of modern embedded processors. If you need acknlowedgement, you need to add that on top yourself.
  • Not master/slave: There are no masters or slaves; all devices can transmit whenever they want. The processor hardware deals with arbitration and contention.
  • OS independence: Not applicable; it's a low-level bus. What you put on top of that is up to you.
  • ANSI C: Again, not applicable.
  • Speed: Typically, up to 1 Mbps up to 40 m; you can choose your own speed for your application.

As mentioned, its definition is fairly low-level, so there's still work to be done to turn it into a full protocol to meet your needs. However, the fact that a lot of the work is done in hardware for you does it make very useful for a variety of applications.

Steve Melnikoff
  • 2,620
  • 1
  • 22
  • 24
  • Thanks Steve, I have looked at CAN in the past (and liked what I've seen). I am really looking for the higher level logic (the acknowledgement, buffering, etc) though. CAN is a VERY strong contender for the physical/datalink layer. I haven't really looked at some of the projects like CANopen that address some of these issues though, and definitely will. – Gabe Jul 21 '09 at 18:52
2

Would you consider the MODBUS protocol? It is master/slave oriented, so the slave could not initiate the transfer, but otherwise is lightweight for implementation, free, and well supported with high level tools. You should just get a grasp on their terminology /like holding register, input register, output coil etc).

Phy level could be RS232, RS485, Ethernet...

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Drazen Cika
  • 291
  • 2
  • 8
2

Have a look at Microcontroller Internet Network (MIN):

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

Inspired by CAN but using standard UART hardware, with Fletcher's checksum and frame format checking for error detection and byte-stuffing to mark a frame header.

Ken Tindell
  • 343
  • 4
  • 7
1

Take a look at Profibus.

If you don't want master/slave, I think you ought to do the arbitration with hardware (Canbus, FlexRay).

KeyserSoze
  • 2,501
  • 1
  • 16
  • 17
  • I would like to avoid master/slave, and if possible, token ring. I've never actually implemented a token ring network before, but have heard bad things. I'm open to possibly using CAN or FlexRay at the datalink/physical layers. – Gabe Jul 21 '09 at 17:52
  • 1
    I wouldn't describe Profibus as lightweight, nor fast. – Steve Melnikoff Jul 21 '09 at 18:14
  • I don't think FlexRay is suitable. FlexRay has its own physical layer and is synchronous. Its main point is redundant clock synchronization, so there are several masters. – starblue Jul 26 '09 at 11:35