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

Committer:
altasoul
Date:
Wed Oct 30 05:01:45 2013 +0000
Revision:
17:93011ddbd0a2
Parent:
16:2d3937773625
Child:
18:8665cc17b30d
for publication

Who changed what in which revision?

UserRevisionLine numberNew contents of line
altasoul 0:0547c8bf304f 1 /*
altasoul 0:0547c8bf304f 2 * Copyright (c) 2013 Tom Soulanille
altasoul 0:0547c8bf304f 3 *
altasoul 16:2d3937773625 4 *
altasoul 16:2d3937773625 5 * Licensed under the Apache License, Version 2.0 (the "License");
altasoul 16:2d3937773625 6 * you may not use this file except in compliance with the License.
altasoul 16:2d3937773625 7 * You may obtain a copy of the License at
altasoul 0:0547c8bf304f 8 *
altasoul 16:2d3937773625 9 * http://www.apache.org/licenses/LICENSE-2.0
altasoul 0:0547c8bf304f 10 *
altasoul 16:2d3937773625 11 * Unless required by applicable law or agreed to in writing, software
altasoul 16:2d3937773625 12 * distributed under the License is distributed on an "AS IS" BASIS,
altasoul 16:2d3937773625 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
altasoul 16:2d3937773625 14 * See the License for the specific language governing permissions and
altasoul 16:2d3937773625 15 * limitations under the License.
altasoul 0:0547c8bf304f 16 */
altasoul 0:0547c8bf304f 17
altasoul 0:0547c8bf304f 18 #ifndef RTOS_SERIAL_H
altasoul 0:0547c8bf304f 19 #define RTOS_SERIAL_H
altasoul 0:0547c8bf304f 20
altasoul 0:0547c8bf304f 21 #include "mbed.h"
altasoul 0:0547c8bf304f 22 #include "rtos.h"
altasoul 0:0547c8bf304f 23
altasoul 0:0547c8bf304f 24 #define MBED_RTOS_SERIAL_VERSION_MAJOR 0
altasoul 8:3644d12758da 25 #define MBED_RTOS_SERIAL_VERSION_MINOR 1
altasoul 11:bc067b42f8e0 26 #define MBED_RTOS_SERIAL_VERSION_EDIT 6
altasoul 0:0547c8bf304f 27
altasoul 9:b664b4f9f93d 28 #define RTOS_SERIAL_TX_THREAD 1
altasoul 12:be7883573c91 29 #define RTOS_SERIAL_TX_THREAD_STACK_SIZE 1024 /* FIXME: figure out good value */
altasoul 0:0547c8bf304f 30
altasoul 0:0547c8bf304f 31 /*
altasoul 0:0547c8bf304f 32 from Serial.h:
altasoul 0:0547c8bf304f 33 class Serial : public Stream {
altasoul 0:0547c8bf304f 34
altasoul 0:0547c8bf304f 35 public:
altasoul 0:0547c8bf304f 36 Serial(PinName tx, PinName rx, const char *name=NULL);
altasoul 0:0547c8bf304f 37 ...
altasoul 0:0547c8bf304f 38 protected:
altasoul 0:0547c8bf304f 39 ...
altasoul 0:0547c8bf304f 40 serial_t _serial;
altasoul 0:0547c8bf304f 41
altasoul 0:0547c8bf304f 42 from serial_api.h:
altasoul 0:0547c8bf304f 43 typedef struct serial_s serial_t;
altasoul 0:0547c8bf304f 44
altasoul 0:0547c8bf304f 45 from objects.h:
altasoul 0:0547c8bf304f 46 struct serial_s {
altasoul 0:0547c8bf304f 47 LPC_UART_TypeDef *uart;
altasoul 0:0547c8bf304f 48 int index;
altasoul 0:0547c8bf304f 49 };
altasoul 0:0547c8bf304f 50
altasoul 0:0547c8bf304f 51 from LPC17xx.h:
altasoul 0:0547c8bf304f 52 typedef struct
altasoul 0:0547c8bf304f 53 {
altasoul 0:0547c8bf304f 54 union {
altasoul 0:0547c8bf304f 55 __I uint8_t RBR;
altasoul 0:0547c8bf304f 56 __O uint8_t THR;
altasoul 0:0547c8bf304f 57 __IO uint8_t DLL;
altasoul 0:0547c8bf304f 58 uint32_t RESERVED0;
altasoul 0:0547c8bf304f 59 };
altasoul 0:0547c8bf304f 60 union {
altasoul 0:0547c8bf304f 61 __IO uint8_t DLM;
altasoul 0:0547c8bf304f 62 __IO uint32_t IER;
altasoul 0:0547c8bf304f 63 };
altasoul 0:0547c8bf304f 64 union {
altasoul 0:0547c8bf304f 65 __I uint32_t IIR;
altasoul 0:0547c8bf304f 66 __O uint8_t FCR;
altasoul 0:0547c8bf304f 67 };
altasoul 0:0547c8bf304f 68 __IO uint8_t LCR;
altasoul 0:0547c8bf304f 69 uint8_t RESERVED1[7];
altasoul 0:0547c8bf304f 70 __I uint8_t LSR;
altasoul 0:0547c8bf304f 71 uint8_t RESERVED2[7];
altasoul 0:0547c8bf304f 72 __IO uint8_t SCR;
altasoul 0:0547c8bf304f 73 uint8_t RESERVED3[3];
altasoul 0:0547c8bf304f 74 __IO uint32_t ACR;
altasoul 0:0547c8bf304f 75 __IO uint8_t ICR;
altasoul 0:0547c8bf304f 76 uint8_t RESERVED4[3];
altasoul 0:0547c8bf304f 77 __IO uint8_t FDR;
altasoul 0:0547c8bf304f 78 uint8_t RESERVED5[7];
altasoul 0:0547c8bf304f 79 __IO uint8_t TER;
altasoul 0:0547c8bf304f 80 uint8_t RESERVED6[39];
altasoul 0:0547c8bf304f 81 __IO uint32_t FIFOLVL;
altasoul 0:0547c8bf304f 82 } LPC_UART_TypeDef;
altasoul 0:0547c8bf304f 83
altasoul 0:0547c8bf304f 84 */
altasoul 0:0547c8bf304f 85
altasoul 15:5f38a747ba08 86 /** An RTOS-friendly serial port
altasoul 15:5f38a747ba08 87 */
altasoul 12:be7883573c91 88 class RTOS_Serial : public RawSerial {
altasoul 0:0547c8bf304f 89 public:
altasoul 0:0547c8bf304f 90
altasoul 17:93011ddbd0a2 91 /** Create an RTOS_Serial connected to the specified UART pins.
altasoul 15:5f38a747ba08 92 *
altasoul 15:5f38a747ba08 93 * @param tx PinName of the UART output (transmission) pin
altasoul 15:5f38a747ba08 94 * @param rx PinName of the UART input (reception) pin
altasoul 15:5f38a747ba08 95 * @param name (optional) A string to identify the object
altasoul 15:5f38a747ba08 96 */
altasoul 0:0547c8bf304f 97 RTOS_Serial(PinName tx, PinName rx, const char *name=NULL);
altasoul 15:5f38a747ba08 98
altasoul 17:93011ddbd0a2 99 /** Send a character.
altasoul 15:5f38a747ba08 100 * If the output queue is full it yields until it can enqueue
altasoul 15:5f38a747ba08 101 *
altasoul 15:5f38a747ba08 102 * @param c character to queue for transmission
altasoul 15:5f38a747ba08 103 * @returns c, or EOF on failure (which should never happen)
altasoul 15:5f38a747ba08 104 */
altasoul 15:5f38a747ba08 105 int putc(int c);
altasoul 15:5f38a747ba08 106
altasoul 17:93011ddbd0a2 107 /** Get a character.
altasoul 15:5f38a747ba08 108 * Yields to other threads until a character is available
altasoul 15:5f38a747ba08 109 *
altasoul 15:5f38a747ba08 110 * @param timeout (optional) milliseconds to wait for a character (default forever)
altasoul 15:5f38a747ba08 111 * @returns the next character, or EOF if none available within timeout
altasoul 15:5f38a747ba08 112 */
altasoul 14:33d60e4eb215 113 int getc(int timeout = osWaitForever);
altasoul 15:5f38a747ba08 114
altasoul 17:93011ddbd0a2 115 /** Put a null-terminated string of characters.
altasoul 15:5f38a747ba08 116 *
altasoul 15:5f38a747ba08 117 * @param s the string
altasoul 15:5f38a747ba08 118 * @returns the number of characters enqueued for transmission, or EOF on error
altasoul 15:5f38a747ba08 119 */
altasoul 2:891773cc33fd 120 int puts(const char *s);
altasoul 14:33d60e4eb215 121 // int readable();
altasoul 14:33d60e4eb215 122 // int writeable();
altasoul 0:0547c8bf304f 123 int get_index();
altasoul 17:93011ddbd0a2 124 /** Obtain the baud rate of the UART.
altasoul 15:5f38a747ba08 125 *
altasoul 15:5f38a747ba08 126 * @returns the baud rate of the UART (tx and rx are the same)
altasoul 15:5f38a747ba08 127 */
altasoul 11:bc067b42f8e0 128 int get_baud();
altasoul 15:5f38a747ba08 129
altasoul 2:891773cc33fd 130 Queue<int, 16> rx_q;
altasoul 12:be7883573c91 131 const char *name;
altasoul 12:be7883573c91 132
altasoul 0:0547c8bf304f 133 protected:
altasoul 0:0547c8bf304f 134 DigitalOut *ledp;
altasoul 5:5d388d1d7987 135 int uart_number;
altasoul 0:0547c8bf304f 136 Queue<int, 16> tx_q;
altasoul 0:0547c8bf304f 137 int parent_putc(int);
altasoul 1:5a66fddad7c4 138
altasoul 12:be7883573c91 139 static void threadStarter(void const *p);
altasoul 13:2fb32235253c 140 void tx_emitter();
altasoul 12:be7883573c91 141
altasoul 12:be7883573c91 142 Thread _tx_thread;
altasoul 8:3644d12758da 143 void rx_isr();
altasoul 8:3644d12758da 144 void tx_isr();
altasoul 0:0547c8bf304f 145 };
altasoul 0:0547c8bf304f 146
altasoul 0:0547c8bf304f 147 #endif