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
Diff: rtos_serial.cpp
- 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] = {