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-24
Revision:
13:2fb32235253c
Parent:
12:be7883573c91
Child:
14:33d60e4eb215

File content as of revision 13:2fb32235253c:

/*
 * 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;

*/

class RTOS_Serial : public RawSerial {
  public:

    RTOS_Serial(PinName tx, PinName rx, const char *name=NULL);
    int putc(int c);    
    int getc();
    int puts(const char *s);
    int get_index();
    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