views:

588

answers:

4

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.

+3  A: 

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

Javier
love it, that's exactly the kind of thing I'm looking for
Gabe
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
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
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
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
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
A: 

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
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
I wouldn't describe Profibus as lightweight, nor fast.
Steve Melnikoff
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
+2  A: 

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
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
+2  A: 

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
I like the looks of HDLC a lot. Have you used it successfully in the past?
Gabe