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:
- 1:5a66fddad7c4
- Parent:
- 0:0547c8bf304f
- Child:
- 2:891773cc33fd
--- a/rtos_serial.cpp Fri Oct 18 02:55:07 2013 +0000 +++ b/rtos_serial.cpp Fri Oct 18 03:39:24 2013 +0000 @@ -30,11 +30,11 @@ const PinName leds[] = {LED1,LED2,LED3,LED4}; ledp = new DigitalOut(leds[get_index()]); tx_emitter_threadp = new Thread(tx_emitter, (void *) this); -}; + tx_tp[get_index()] = tx_emitter_threadp; + attach(tx_isr[get_index()], Serial::TxIrq); +} -Thread* RTOS_Serial::tx_tp[4] = { NULL, NULL, NULL, NULL }; - -serial_t RTOS_Serial::get_serial() { return _serial; }; +serial_t RTOS_Serial::get_serial() { return _serial; } int RTOS_Serial::get_index() { return _serial.index; } @@ -58,6 +58,33 @@ //tx_emitter_threadp->signal_set(0x1); tx_tp[0]->signal_set(0x01); } +// class method +void RTOS_Serial::UART1_TX_ISR(){ + uint32_t IRR = LPC_UART1->IIR; + //tx_emitter_threadp->signal_set(0x1); + tx_tp[1]->signal_set(0x01); +} +// class method +void RTOS_Serial::UART2_TX_ISR(){ + uint32_t IRR = LPC_UART2->IIR; + //tx_emitter_threadp->signal_set(0x1); + tx_tp[2]->signal_set(0x01); +} +// class method +void RTOS_Serial::UART3_TX_ISR(){ + uint32_t IRR = LPC_UART3->IIR; + //tx_emitter_threadp->signal_set(0x1); + tx_tp[3]->signal_set(0x01); +} + +func RTOS_Serial::tx_isr[4] = { + &RTOS_Serial::UART0_TX_ISR, + &RTOS_Serial::UART1_TX_ISR, + &RTOS_Serial::UART2_TX_ISR, + &RTOS_Serial::UART3_TX_ISR, +}; + +Thread* RTOS_Serial::tx_tp[4] = { NULL, NULL, NULL, NULL }; // tx_emitter is a class method void RTOS_Serial::tx_emitter(void const *argument){ @@ -73,7 +100,7 @@ #if 1 evt = sp->tx_q.get(); if (evt.status == osEventMessage) { - //Thread::signal_wait(0x1); + Thread::signal_wait(0x1); *(sp->ledp) = 1; sp->parent_putc(evt.value.v); *(sp->ledp) = 0;