This application will buffer and send lines from up to three serial devices and USB host when connected to via TCP, with telnet or netcat. Written, 02/10/2011-2/14/2011 by Graham Cantin & Special Guest Appearance from Sasha Jevtic (mostly Sasha)
Dependencies: EthernetNetIf MODDMA MODGPS MODSERIAL NTPClient mbed
line_util.cpp
- Committer:
- kamilion
- Date:
- 2014-11-06
- Revision:
- 1:29f6c660d174
- Parent:
- 0:5d5265391846
File content as of revision 1:29f6c660d174:
// Line utility functions // 02/13/2011 /* Utility functions for dealing with incoming data */ #include "mbed.h" #include "line_util.h" static LINE_T SLines[NUM_LINES]; // Cirular buffer head pointer static unsigned int HeadLines = 0; // Circular buffer tail pointer static unsigned int TailLines = 0; // Allow inserting things into the queue? static bool AllowInsert = false; // These are the source type names when output into a line struct. const char* const LINE_SRC_NAMES[] = { "INVALID", "DBG", "KIS", "GPS", "IMU", "WHL", "BUT", "NONE" }; // Strips any carrage returns or line feeds from incoming lines, once received unsigned int strip_crlf(char* src) { unsigned int i = 0; while(src[i] != 0) { if((src[i] == '\n') || (src[i] == '\r')) { src[i] = 0; return i; } i++; } return i; } // Line Buffers: Get the current level of queue fullness in # of lines unsigned int SLines_get_fill() { unsigned int ret; __disable_irq(); // IRQs off, don't bother us, we're working. ret = (TailLines >= HeadLines ? TailLines - HeadLines : NUM_LINES - (HeadLines - TailLines)); __enable_irq(); // Back to reality, more data calls. return ret; } // Line Buffers: Get the current capacity of the queue unsigned int SLines_get_capacity() { return (NUM_LINES - 1); } // Line Buffers: Put a line into the queue LINE_T* SLine_put(LINE_T* line) { unsigned int fill; LINE_T* ret; // Empty struct to return __disable_irq(); // IRQs off, don't bother us, we're working. // Are we allowing inserts? If not, just Return a NULL struct early. if (!AllowInsert) { ret = NULL; __enable_irq(); // Back to reality, more data calls. return ret; } fill = (TailLines >= HeadLines ? TailLines - HeadLines : NUM_LINES - (HeadLines - TailLines)); if (fill != (NUM_LINES - 1)) { TailLines = (TailLines + 1) % NUM_LINES; memcpy(&(SLines[TailLines]), line, sizeof(LINE_T)); ret = &(SLines[TailLines]); } else { ret = NULL; } __enable_irq(); // Back to reality, more data calls. return ret; } // Line Buffers: Get a line from the queue LINE_T* SLine_get() { bool empty; // Is the queue empty? LINE_T* ret; // Pointer to the line we're about to return __disable_irq(); // IRQs off, don't bother us, we're working. // Check to see if the queue is empty. empty = (HeadLines == TailLines ? true : false); if (!empty) { // if the queue is not empty ret = &(SLines[HeadLines]); // Return a line. } else { // the queue was empty. ret = NULL; // Return an empty struct. } // Note that the pointer to the line struct that we're returning is only // guaranteed good until it is removed. In fact, the preservation of // the data pointed to is the only reason that "get" and "remove" are // seperate operations. __enable_irq(); return ret; } // Line Buffers: Remove the line from the queue once a GET succeeds void SLine_remove() { bool empty; // Is the queue empty? __disable_irq(); // IRQs off, don't bother us, we're working. // Check to see if the queue is empty. empty = (HeadLines == TailLines ? true : false); if (!empty) { // If the queue is not empty... HeadLines = (HeadLines + 1) % NUM_LINES; // The axe falls, the line expires. // The tricky part, of course, is that the data is not // immediately invalidated. Any pointers to the now-removed line // will point to valid data until a put() operation overwrites // the line in question. Of course, the code that removes the line // won't typically be the code that also performs insertions, so it // will never know when that happens. Moral of the story: finish what // you're doing with a gotten line before removing it. } __enable_irq(); // Back to reality, more data calls. } // Line Buffers: Clear the queue void SLine_clear() { __disable_irq(); // IRQs off, don't bother us, we're working. HeadLines = TailLines = 0; // Set both ends of the snake at oroboros. __enable_irq(); // Back to reality, more data calls. } // Line Buffers: Open or Close the queue to incoming lines void SLine_put_control(bool gate) { __disable_irq(); // IRQs off, don't bother us, we're working. AllowInsert = gate; // Set one end of the snake open. __enable_irq(); // Back to reality, more data calls. }