RTEMS Logo

RTEMS 4.9.2 On-Line Library


Console Driver Termios and Interrupt Driven IO

PREV UP NEXT Bookshelf BSP and Device Driver Development Guide

8.4.3: Termios and Interrupt Driven IO

The UART generally generates interrupts when it is ready to accept or to emit a number of characters. In this mode, the interrupt subroutine is the core of the driver.

The my_driver_interrupt_handler is responsible for processing asynchronous interrupts from the UART. There may be multiple interrupt handlers for a single UART. Some UARTs can generate a unique interrupt vector for each interrupt source such as a character has been received or the transmitter is ready for another character.

In the simplest case, the my_driver_interrupt_handler will have to check the status of the UART and determine what caused the interrupt. The following describes the operation of an my_driver_interrupt_handler which has to do this:

static void my_driver_interrupt_handler(
    rtems_vector_number vector,
    void *arg
)
{
    my_driver_entry *e = (my_driver_entry *) arg;
    char buf [N];
    int n = 0;

    /*
     * Check if we have received something.  The function reads the
     * received characters from the device and stores them in the
     * buffer.  It returns the number of read characters.
     */
    n = my_driver_read_received_chars(e, buf, N);
    if (n > 0) {
        /* Hand the data over to the Termios infrastructure */
        rtems_termios_enqueue_raw_characters(e->tty, buf, n);
    }

    /*
     * Check if we have something transmitted.  The functions returns
     * the number of transmitted characters since the last write to the
     * device.
     */
    n = my_driver_transmitted_chars(e);
    if (n > 0) {
        /*
         * Notify Termios that we have transmitted some characters.  It
         * will call now the interrupt write function if more characters
         * are ready for transmission.
         */
        rtems_termios_dequeue_characters(e->tty, n);
    }
}

The my_driver_interrupt_write function is responsible for telling the device that the n characters at buf are to be transmitted. The return value may be arbitrary since it is not checked from Termios. It is guaranteed that n is greater than zero. This routine is invoked either from task context with disabled interrupts to start a new transmission process with exactly one character in case of an idle output state or from the interrupt handler to refill the transmitter. If the routine is invoked to start the transmit process the output state will become busy and Termios starts to fill the output buffer. If the transmit interrupt arises before Termios was able to fill the transmit buffer you will end up with one interrupt per character.

static int my_driver_interrupt_write(int minor, const char *buf, int n)
{
    my_driver_entry *e = &my_driver_table [minor];

    /*
     * There is no need to check the minor number since it is derived
     * from a file descriptor.  The upper layer takes care that it is
     * in a valid range.
     */

    /*
     * Tell the device to transmit some characters from buf (less than
     * or equal to n).  If the device is finished it should raise an
     * interrupt.  The interrupt handler will notify Termios that these
     * characters have been transmitted and this may trigger this write
     * function again.  You may have to store the number of outstanding
     * characters in the device data structure.
     */

    return 0;
}


PREV UP NEXT Bookshelf BSP and Device Driver Development Guide

Copyright © 1988-2008 OAR Corporation