Inherit from Serial and use software buffers for TX and RX. This allows the UART peripherals to operate in a IRQ driven mode. Overrides most (but not all) stdio functions as Serial did

Dependencies:   Buffer

Dependents:   buffered_serial_test BLE_Police_HRM evena_BLE_Police_HRM df-2014-workshop-rfid-case-generator-k64f ... more

Example

 #include "mbed.h"
 #include "BufferedSerial.h"

 BufferedSerial pc(USBTX, USBRX);

 int main()
 {
     pc.baud(115200);
   
     while(1)
     {
         Timer s;
       
         s.start();
         pc.printf("Hello World - buff\n");
         int buffered_time = s.read_us();
         wait(0.1f); // give time for the buffer to empty
       
         s.reset();
         printf("Hello World - poll\n");
         int polled_time = s.read_us();
         s.stop();
         wait(0.1f); // give time for the buffer to empty
       
         pc.printf("printf buffered took %d us\n", buffered_time);
         pc.printf("printf polled took %d us\n", polled_time);
         wait(0.5f);
     }
 }

Files at this revision

API Documentation at this revision

Comitter:
sam_grove
Date:
Fri May 24 22:00:26 2013 +0000
Parent:
1:57a11fb5d529
Child:
3:6b76fcf27545
Commit message:
Override virtual member write. Better management of prime to avoid contentious writes under heavy traffic. updated puts to add \n per stdlib puts definition

Changed in this revision

BufferedSerial.cpp Show annotated file Show diff for this revision Revisions of this file
BufferedSerial.h Show annotated file Show diff for this revision Revisions of this file
--- a/BufferedSerial.cpp	Thu May 23 23:47:04 2013 +0000
+++ b/BufferedSerial.cpp	Fri May 24 22:00:26 2013 +0000
@@ -66,15 +66,16 @@
 
 int BufferedSerial::puts(const char *s)
 {
-    const char *size = s;
+    const char* ptr = s;
     
-    while(*(s) != 0)
+    while(*(ptr) != 0)
     {
-        _txbuf = *(s++);
+        _txbuf = *(ptr++);
     }
+    _txbuf = '\n';  // done per puts definition
     BufferedSerial::prime();
     
-    return s - size;
+    return (ptr - s) + 1;
 }
 
 int BufferedSerial::printf(const char* format, ...)
@@ -88,18 +89,33 @@
     // this may not hit the heap but should alert the user anyways
     if(r > sizeof(buf))
     {
-        ERROR("Buffer Overwrite Occured!\n");
+        ERROR("Buffer Overflow on the Stack Occured!\n");
     }
-    r = BufferedSerial::puts(buf);
+    r = BufferedSerial::write(buf, r);
     va_end(arg);
     
     return r;
 }
 
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+    const char* ptr = (const char*)s;
+    const char* end = ptr + length;
+    
+    while (ptr != end)
+    {
+        _txbuf = *(ptr++);
+    }
+    BufferedSerial::prime();
+    
+    return ptr - (const char*)s;  
+}
+
+
 void BufferedSerial::rxIrq(void)
 {
     // read from the peripheral and see if things are available
-    while(serial_readable(&_serial))
+    if(serial_readable(&_serial))
     {
         _rxbuf = serial_getc(&_serial); // if so load them into a buffer
     }
@@ -110,7 +126,7 @@
 void BufferedSerial::txIrq(void)
 {
     // see if there is room in the hardware buffer and something is in the software buffer
-    while(serial_writable(&_serial) && _txbuf.available())
+    if(serial_writable(&_serial) && _txbuf.available())
     {
         serial_putc(&_serial, (int)_txbuf.get());
     }
@@ -120,12 +136,15 @@
 
 void BufferedSerial::prime(void)
 {
-    __disable_irq();    // make sure not to cause contention in the irq 
-    BufferedSerial::txIrq();    // prime the txirq to stoke transmit
-    __enable_irq();
+    // if already busy then the irq will pick this up
+    if(serial_writable(&_serial))
+    {
+        __disable_irq();    // make sure not to cause contention in the irq 
+        BufferedSerial::txIrq();    // prime the txirq - only write to hardware in one place
+        __enable_irq();
+    }
     
     return;
 }
 
 
-
--- a/BufferedSerial.h	Thu May 23 23:47:04 2013 +0000
+++ b/BufferedSerial.h	Fri May 24 22:00:26 2013 +0000
@@ -73,8 +73,8 @@
 class BufferedSerial : public Serial 
 {
 private:
-    Buffer <char> _rxbuf;
-    Buffer <char> _txbuf;
+    Buffer <char>   _rxbuf;
+    Buffer <char>   _txbuf;
  
     void rxIrq(void);
     void txIrq(void);
@@ -110,22 +110,28 @@
     
     /** Write a single byte to the BufferedSerial Port.
      *  @param c The byte to write to the Serial Port
-     *  @return The byte that was written to the Serial Port
+     *  @return The byte that was written to the Serial Port Buffer
      */
     virtual int putc(int c);
     
     /** Write a string to the BufferedSerial Port. Must be NULL terminated
      *  @param s The string to write to the Serial Port
-     *  @return The number of bytes written to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
      */
     virtual int puts(const char *s);
     
     /** Write a formatted string to the BufferedSerial Port.
      *  @param format The string + format specifiers to write to the Serial Port
-     *  @return The number of bytes written to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
      */
     virtual int printf(const char* format, ...);
     
+    /** Write data to the Buffered Serial Port
+     *  @param s A pointer to data to send
+     *  @param length The amount of data being pointed to
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual ssize_t write(const void *s, std::size_t length);
 };
 
 #endif