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:
- 18:8665cc17b30d
- Parent:
- 17:93011ddbd0a2
- Child:
- 19:d974f46f6882
File content as of revision 18:8665cc17b30d:
/* * Copyright (c) 2013 Tom Soulanille * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #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 * * Example: * @code * // Bridge the USB serial interface to a uart * #include "mbed.h" * #include "rtos.h" * #include "rtos_serial.h" * * DigitalOut myled(LED1); * * void p_to_p(const void* arg) { * RTOS_Serial** ports = (RTOS_Serial**) arg; * while (true) ports[1]->putc(ports[0]->getc()); * } * * int main() { * RTOS_Serial host(USBTX, USBRX); * RTOS_Serial uart(p13, p14); * RTOS_Serial *host_uart_ports[] = {&host, &uart}; * Thread host_to_port_thread(p_to_p, (void*) host_uart_ports); * RTOS_Serial *uart_host_ports[] = {&uart, &host}; * Thread port_to_host_thread(p_to_p, (void*) uart_host_ports); * * while (true) { * myled = !myled; * Thread::wait(400); * } * } */ 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