Inconsistencies around TERMIOS_TASK_DRIVEN and deviceOutputUsesInterrupts

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Aug 1 11:20:49 UTC 2013


Hello R.,

On 2013-08-01 12:51, R. Diez wrote:
> Hallo all:
>
> File cpukit/libcsupport/include/rtems/termiostypes.h defines the following constants:
>
>    /*
>     * FIXME: this should move to libio.h!
>     * values for rtems_termios_callbacks.outputUsesInterrupts
>     */
>    #define TERMIOS_POLLED      0
>    #define TERMIOS_IRQ_DRIVEN  1
>    #define TERMIOS_TASK_DRIVEN 2
>
> However, some modules initialise rtems_termios_callbacks structures with fixed values like this:
>      .outputUsesInterrupts = 1,
> Others use one of the constants above.
>
> I noticed because some drivers initialise a similar field in structure console_fns with true/false, while others use the same constants as above. Routine console_open() in c/src/lib/libbsp/shared/console.c copies this flag as follows:
>
>    Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts;

yes, this is bad.  The console driver framework has a lot of stuff like this. 
The problem is that from a functional point of view it works well and it seems 
nobody has a budget to fix these more cosmetic issues.

>
> That is copying information from structure console_fns to structure rtems_termios_callbacks, but cptr->pDeviceFns->deviceOutputUsesInterrupts is of type bool, whereas Callbacks.outputUsesInterrupts is an int.
>
> What does TERMIOS_TASK_DRIVEN mean anyway? I didn't manage to find any documentation about it.

If you look at a typical interrupt service routine

static void pl050_interrupt(void *arg)
{
   int minor = (int) arg;
   const console_data *cd = &Console_Port_Data[minor];
   volatile pl050 *regs = pl050_get_regs(minor);
   uint32_t kmiir_rx = PL050_KMIIR_KMIRXINTR;
   uint32_t kmiir_tx = (regs->kmicr & PL050_KMICR_KMITXINTREN) != 0 ?
     PL050_KMIIR_KMITXINTR : 0;
   uint32_t kmiir = regs->kmiir;

   if ((kmiir & kmiir_rx) != 0) {
     char c = (char) PL050_KMIDATA_KMIDATA_GET(regs->kmidata);

     rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1);
   }

   if ((kmiir & kmiir_tx) != 0) {
     rtems_termios_dequeue_characters(cd->termios_data, 1);
   }
}

then you see that two Termios functions are called.  The do a lot of stuff. 
This processing overhead increases the thread dispatch and interrupt latency.

To overcome this issue the TERMIOS_TASK_DRIVEN was added.  Here the interrupt 
handler only signals a special purpose task which performs the input/output 
processing.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber at embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



More information about the devel mailing list