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-18
Revision:
2:891773cc33fd
Parent:
1:5a66fddad7c4
Child:
4:c7113cd0ac4b

File content as of revision 2:891773cc33fd:

/*
 * 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    0
#define MBED_RTOS_SERIAL_VERSION_EDIT     3

#define N_TX_MSGS   5 /* FIXME: parameterize */
#define OPTION_USE_MAIL_FOR_TX 1

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

*/

//FIXME:
typedef void (*func)();

class RTOS_Serial : public Serial {
  public:

    RTOS_Serial(PinName tx, PinName rx, const char *name=NULL);
    int putc(int c);    
    int puts(const char *s);
    int getc();
    int get_index();
    Queue<int, 16> rx_q;
    static RTOS_Serial* rsp[4];

  protected:

    typedef struct {
        char *p;
        int len;
    } tx_mail_t;

    DigitalOut *ledp;
    int _uart_number;
    Queue<int, 16> tx_q;
    int parent_putc(int);
    
    static void tx_emitter(void const *argument);
    static void UART0_TX_ISR(), UART1_TX_ISR(), UART2_TX_ISR(), UART3_TX_ISR();
    static void UART0_RX_ISR(), UART1_RX_ISR(), UART2_RX_ISR(), UART3_RX_ISR();
    static Thread* tx_tp[4];
    static func tx_isr[4];
    static func rx_isr[4];
    Thread* tx_emitter_threadp;
    uint32_t _debug_increment_me;
    void _yow();
    serial_t get_serial();
};

#endif