BSP and Device Driver Development Guide
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; }
BSP and Device Driver Development Guide
Copyright © 1988-2008 OAR Corporation