Just a small test for frames and serial (RS232) communication, with ideas from http://eli.thegreenplace.net/2009/08/20/frames-and-protocols-for-the-serial-port-in-python/
Diff: parser.c
- Revision:
- 0:566fc5f530fe
diff -r 000000000000 -r 566fc5f530fe parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parser.c Wed May 02 06:01:00 2012 +0000 @@ -0,0 +1,113 @@ +/* + * + */ + +#include "mbed.h" +#include "parser.h" + +int wrap_protocol(char *c, string *message, list<string> *messages, char header, char footer, char dle ) { + + static int state = 0; + static int dle_state = 0; + static int index; + static int size; + + + switch (state) { + case 0: // start sending a header if there is a valid message available + if (!messages->empty()) { + *message = messages->front(); + messages->pop_front(); // now that we have the message, delete it from the list + index = 0; // initialize sending the actual message + size = message->size(); + state = 1; + *c = header; + return WRAP_SEND; + } + return WRAP_ABORT; + + case 1: + if ((size == 0) || (index==size)) { + *c = footer; + state = 0; + return WRAP_FINISHED; + } + + *c = (*message)[index]; + + if ( dle_state == 1 ) { + dle_state = 0; + index++; + return WRAP_SEND; + } + + if ( (*c == header) || (*c == footer) || (*c == dle) ) { + dle_state = 1; + *c = dle; + return WRAP_SEND; + } + + index++; + return WRAP_SEND; + } + + // if we reach this point, something went wrong! + return WRAP_ABORT; +} + +void unwrap_protocol(char *c, string *buffer, list<string> *messages, unsigned int max_message_size, + unsigned int max_messages, char header, char footer, char dle ) { + + // these are needed for the internal state of the function + // they are also the reaseon, why this function can only be used in exactly one location + // i.e. the interrupt routine for receiving characters from the RS232 + static int state = 0; + static int dle_state = 0; + + switch (state) { + case 0: + if (*c == header) { + message_led=!message_led; + state = 1; + } + return; + + case 1: + if (*c== header && dle_state==0) { + // new header that is not escaped will set e new message start + buffer->clear(); + return; + } + if (*c == footer && dle_state==0 ) { + // a frame end is only a frame end, if the footer is not escaped + messages->push_back( *buffer ); + buffer->clear(); + state = 0; + message_led=!message_led; + return; + } + + // check length of buffer; clear, if too large; restart search for header! + if (buffer->length() > max_message_size) { + // prevent buffer overflows if someone is flooding us with characters + buffer->clear(); + state=0; + return; + } + + if (*c == dle && dle_state==0) { + // the next character is "escaped" and is part of the message + dle_state = 1; + return; + } + + // probably the easiest and quickest way of resetting the dle_state + dle_state = 0; + + // in all other cases, we found a new character and append it to the buffer + *buffer += *c; + } +} + + +