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
rtos_serial.h
- Committer:
- altasoul
- Date:
- 2013-10-30
- Revision:
- 15:5f38a747ba08
- Parent:
- 14:33d60e4eb215
- Child:
- 16:2d3937773625
File content as of revision 15:5f38a747ba08:
/* * Copyright (c) 2013 Tom Soulanille * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef RTOS_SERIAL_H #define RTOS_SERIAL_H #include "mbed.h" #include "rtos.h" #define MBED_RTOS_SERIAL_VERSION_MAJOR 0 #define MBED_RTOS_SERIAL_VERSION_MINOR 1 #define MBED_RTOS_SERIAL_VERSION_EDIT 6 #define RTOS_SERIAL_TX_THREAD 1 #define RTOS_SERIAL_TX_THREAD_STACK_SIZE 1024 /* FIXME: figure out good value */ /* from Serial.h: class Serial : public Stream { public: Serial(PinName tx, PinName rx, const char *name=NULL); ... protected: ... serial_t _serial; from serial_api.h: typedef struct serial_s serial_t; from objects.h: struct serial_s { LPC_UART_TypeDef *uart; int index; }; from LPC17xx.h: typedef struct { union { __I uint8_t RBR; __O uint8_t THR; __IO uint8_t DLL; uint32_t RESERVED0; }; union { __IO uint8_t DLM; __IO uint32_t IER; }; union { __I uint32_t IIR; __O uint8_t FCR; }; __IO uint8_t LCR; uint8_t RESERVED1[7]; __I uint8_t LSR; uint8_t RESERVED2[7]; __IO uint8_t SCR; uint8_t RESERVED3[3]; __IO uint32_t ACR; __IO uint8_t ICR; uint8_t RESERVED4[3]; __IO uint8_t FDR; uint8_t RESERVED5[7]; __IO uint8_t TER; uint8_t RESERVED6[39]; __IO uint32_t FIFOLVL; } LPC_UART_TypeDef; */ /** An RTOS-friendly serial port */ class RTOS_Serial : public RawSerial { public: /** Create an RTOS_Serial connected to the specified UART pins * * @param tx PinName of the UART output (transmission) pin * @param rx PinName of the UART input (reception) pin * @param name (optional) A string to identify the object */ RTOS_Serial(PinName tx, PinName rx, const char *name=NULL); /** Send a character * If the output queue is full it yields until it can enqueue * * @param c character to queue for transmission * @returns c, or EOF on failure (which should never happen) */ int putc(int c); /** Get a character * Yields to other threads until a character is available * * @param timeout (optional) milliseconds to wait for a character (default forever) * @returns the next character, or EOF if none available within timeout */ int getc(int timeout = osWaitForever); /** Put a null-terminated string of characters * * @param s the string * @returns the number of characters enqueued for transmission, or EOF on error */ int puts(const char *s); // int readable(); // int writeable(); int get_index(); /** Obtain the baud rate of the UART * * @returns the baud rate of the UART (tx and rx are the same) */ int get_baud(); Queue<int, 16> rx_q; const char *name; protected: DigitalOut *ledp; int uart_number; Queue<int, 16> tx_q; int parent_putc(int); static void threadStarter(void const *p); void tx_emitter(); Thread _tx_thread; void rx_isr(); void tx_isr(); }; #endif