An RTOS-friendly Serial interface Its primary benefit is that it never hogs the CPU. An amusing alternative to the traditional ring-bufferd interrupt-serviced systems, it uses short mbed-rtos queues to buffer characters to and from the UART, and a thread to service the transmitter. Short interrupt service routines enqueue received characters and signal the transmit thread when the transmitter is available. WARNING: Do not create RTOS-Serial objects before the RTOS is running! Put them inside your main() block or another function, not in the global initialization.

Dependents:   Test_RDM880_rfid_reader

Revision:
4:c7113cd0ac4b
Parent:
3:5865277b7710
Child:
5:5d388d1d7987
--- a/rtos_serial.cpp	Fri Oct 18 23:22:49 2013 +0000
+++ b/rtos_serial.cpp	Sat Oct 19 05:40:43 2013 +0000
@@ -27,14 +27,15 @@
 {
     const PinName leds[] = {LED1,LED2,LED3,LED4};
     ledp = new DigitalOut(leds[get_index()]);
-    rsp[get_index()] = this;
+    rtos_serial_pointers_by_index[get_index()] = this;
     tx_emitter_threadp = new Thread(tx_emitter, (void *) this);
     tx_tp[get_index()] = tx_emitter_threadp;
-    attach(tx_isr[get_index()], /*Serial::*/TxIrq);
+    attach(rx_isr[get_index()], RxIrq);
+    attach(tx_isr[get_index()], TxIrq);
     tx_emitter_threadp->signal_set(0x01);   // "prime the pump" of the tx-ready signals
 }
 
-RTOS_Serial* RTOS_Serial::rsp[4] = { NULL, NULL, NULL, NULL };
+RTOS_Serial* RTOS_Serial::rtos_serial_pointers_by_index[4] = { NULL, NULL, NULL, NULL };
 
 serial_t RTOS_Serial::get_serial() { return _serial; }
 
@@ -68,7 +69,16 @@
 }
 
 int RTOS_Serial::getc() {
-    return Serial::getc();  //FIXME: stand-in
+    int rv;
+    //return Serial::getc();  //FIXME: stand-in, which fails if we use our RX ISR
+    osEvent evt = rx_q.get();
+    if (evt.status == osEventMessage) {
+        rv = (int) evt.value.v;
+    } else {    //FIXME: find appropriate error reporting if any
+        std::printf("rx_dequeuer() evt.status %d\n", evt.status);
+        rv = EOF;
+    }
+    return rv;
 }
 
 
@@ -108,19 +118,19 @@
 /// ISR's for receiver interrupts
 // class method
 void RTOS_Serial::UART0_RX_ISR(){
-    RTOS_Serial::rsp[0]->rx_q.put((int *)LPC_UART0->RBR);
+    RTOS_Serial::rtos_serial_pointers_by_index[0]->rx_q.put((int *)LPC_UART0->RBR);
 }
 // class method
 void RTOS_Serial::UART1_RX_ISR(){
-    RTOS_Serial::rsp[1]->rx_q.put((int *)LPC_UART1->RBR);
+    RTOS_Serial::rtos_serial_pointers_by_index[1]->rx_q.put((int *)LPC_UART1->RBR);
 }
 // class method
 void RTOS_Serial::UART2_RX_ISR(){
-    RTOS_Serial::rsp[2]->rx_q.put((int *)LPC_UART2->RBR);
+    RTOS_Serial::rtos_serial_pointers_by_index[2]->rx_q.put((int *)LPC_UART2->RBR);
 }
 // class method
 void RTOS_Serial::UART3_RX_ISR(){
-    RTOS_Serial::rsp[3]->rx_q.put((int *)LPC_UART3->RBR);
+    RTOS_Serial::rtos_serial_pointers_by_index[3]->rx_q.put((int *)LPC_UART3->RBR);
 }
 
 func RTOS_Serial::rx_isr[4] = {