12

I’m working on with an embedded device that is connected to PC using rs232 (rs232 over USB).

I’m thinking about developing my own protocol:

<MAGIC><LENGTH><BINARY DATA><CRC>

but I don’t want to reinvent the wheel.

Please note that: I'm thinking about quite restricted device: 4kb of RAM, no kernel, nor standard C lib.

Can you think about a standard way to do this (maybe open source library)?

If you code your own solution do have any best practices?

  • Do you use MAGIC bytes also at the end of packages?
  • Maybe it is better to use time gaps instead of delimiters?
  • How do you find the beginning of packages in a stream binary data?
  • Maybe it is better to use text protocols?

UPDATE: Please re read the question. I shouldn't ask for library but for good practices.

Piotr Czapla
  • 25,734
  • 24
  • 99
  • 122
  • Similar to: http://stackoverflow.com/questions/815758/ – Steve Melnikoff May 03 '09 at 14:08
  • Should the 3rd bullet point be: "how do you find the beginning of packets in a stream of binary data"? – Steve Melnikoff May 03 '09 at 14:17
  • I added to my answer at http://stackoverflow.com/questions/815758/simple-serial-point-to-point-communication-protocol/815813#815813 it should help you as well. – Rex Logan May 03 '09 at 20:08
  • The approach I took in MIN (See here: http://stackoverflow.com/a/28589141/2012014) for finding the start of a frame is to have three 0xAA bytes in a row, and to use byte-stuffing to ensure that three in a row can never appear in the rest of the frame. It's robust to implement: just reset the receiving protocol state machine whenever 0xAA 0xAA 0xAA appears. – Ken Tindell Feb 18 '15 at 18:37

3 Answers3

4

See this answer I gave to a very similar question regarding details of a simple protocol.

To respond to your specific points:

  1. "Magic" bytes at the end of packets don't do any harm, but they're redundant if you already know how long the packet is supposed to be, and have a CRC.
  2. It can be sensible to specifiy timeout times, so if there's too big a gap between bytes within one packet, then an error is flagged. Having used Modbus, I'm not convinced of the value of using time-based delimiters elsewhere.
  3. Do you mean, "how do you find the beginning of packets in a stream of binary data"? If so, maybe specify a minimum gap between packets, and/or require the recipient to acknolwedge after every packet.
  4. Makes it easier for debugging, and doesn't require any special software on the PC, but not very efficient. Of course, if usability is more important than efficiency, than a text-based system is entirely appropriate.
Community
  • 1
  • 1
Steve Melnikoff
  • 2,620
  • 1
  • 22
  • 24
  • The link you provided answers my question regarding the beginning of packets. Reading Asynchronous framing of HDLC was very helpful. – Piotr Czapla May 03 '09 at 15:33
  • 1
    One point I've not seen mentioned: even if the preceding byte has a framing error due to line noise, the byte following a byte value of $00, $80, $C0, $F0, $F8, $FC, $FE, or $FF will always be received correctly. If packets will be sent back to back without acknowledgment (to allow maximum throughput; hopefully the first packet's ack will arrive while the second packet is being transmitted) it may be useful to end each packet with one of those byte values, so that a framing error in one packet will not corrupt the next one. – supercat Jan 25 '11 at 21:24
3

For something like this by the time you get an existing solution to work on your device, it would have been easier just to reinvent the wheel.

void buffer_packet(unsigned char rx_byte)
{
    static unsigned char byte_count = 0;
    static unsigned char packet[8];

    packet[byte_count++] = rx_byte;
    if (byte_count == 8)
    {
        unsigned char crc = calculate_crc(packet, 8);

        write_uart(0x55);
        write_uart(8);
        while (byte_count--)
        {
            write_uart(packet[7 - byte_count]);
        }
        write_uart(crc);
    }
}

Or maybe I am underestimating your problem. If you're looking for how to generate the RS232 bits look in your microcontrollers datasheet.

James
  • 351
  • 1
  • 2
  • 6
  • I didn't stated my question clearly enough. The task looks easy but I'm pretty new to embedded programing so I'm interested in best practices. – Piotr Czapla May 02 '09 at 18:22
0

About the only thing there beyond your I/O primitives is going to be the CRC calculation. There's a nifty article, with code, here.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • The article looks nice :). Thank you. But the CRC isn't the problem as we have it already implemented for RF transmission. – Piotr Czapla May 02 '09 at 17:37