handling a uart interrupt n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Handling a UART interrupt PowerPoint Presentation
Download Presentation
Handling a UART interrupt

Loading in 2 Seconds...

play fullscreen
1 / 17

Handling a UART interrupt - PowerPoint PPT Presentation


  • 101 Views
  • Uploaded on

Handling a UART interrupt. A look at some recent changes in the Linux kernel’s programming interface for device-interrupts. The new ‘anchor’ cluster.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Handling a UART interrupt' - thuy


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
handling a uart interrupt

Handling a UART interrupt

A look at some recent changes in the Linux kernel’s programming interface for device-interrupts

the new anchor cluster
The new ‘anchor’ cluster
  • To reduce contention for CS workstations that have null-modem cables attached, we are bringing online an additional cluster of eight servers – you access them remotely

‘anchor00’

‘anchor01’

‘anchor02’

‘anchor03’

‘anchor04’

‘anchor05’

‘anchor06’

‘anchor07’

Thanks to overnight efforts by Alex Fedosov and our CS support-team! 

ldd3 kernel 2 6 10
LDD3: kernel 2.6.10
  • Our text “Linux Device Drivers (3rd Ed)” is published by O’Reilly in February 2005
  • The kernel version it covers is 2.6.10
  • But in our classroom we are using a more recent version of the kernel (i.e., 2.6.22.5) which was released in mid-August 2007
  • Various changes (improvements) are now implemented (and differ from LDD3 book)
example 1
Example 1
  • Our textbook shows the prototype for a device-driver’s interrupt service routine:

irqreturn_t isr( int irq, void *dev_id, struct pt_regs *regs );

  • But this has changed in kernel 2.6.22.5 to:

Irqreturn_t isr( int irq, void *dev_id );

  • What prompted the kernel developers to remove that third function-argument?
  • Just a guess, but probably it was because programmers were not actually using it
example 2
Example 2
  • The kernel’s header-files <asm/signal.h> provided symbolic names for important interrupt-related constants in 2.6.10:

#define SA_SHIRQ 0x04000000

  • Such definitions, formerly replicated for each supported CPU architecture, have now been consolidated (and renamed) in the kernel header-file <linux/interrupt.h>:

#define IRQF_SHARED 0x00000080

consequences
Consequences
  • If you try to apply the textbook discussion about interrupt-handlers to your LKMs for this class, the compiler will generate error messages and/or warning messages
  • So you will need to use the “new” kernel’s interfaces, not documented in our textbook
  • Maybe you can locate an online tutorial, or look at other device-drivers’ source-code
our uartintr c module
Our ‘uartintr.c’ module
  • We have written a kernel module that you can study (and experiment with) showing an interrupt-handler for the UART device that we created purely for demonstration purposes using kernel version 2.6.22.5
  • Obviously you would need to modify it if you wanted to use an interrupt-handler in your solution for our course’s Project #2
slide8

Module’s components

The LKM layout

module’s ‘payload’

is just a single

callback-function

that will ‘handle’ a

UART interrupt

The isr function

registers the ‘isr’

and then enables

the UART device

to generate

interrupt-signals

init

the usual pair of

module-administration

functions

exit

disables the UART’s

interrupt-signals

and then unregisters

this module’s ‘isr’

slide9

Interrupt Identification Register

7 6 5 4 3 2 1 0

0

0

‘highest priority’

UART interrupt

still pending

00 = FIFO-mode has not been enabled

11 = FIFO-mode is currently enabled

highest

011 = receiver line-status

010 = received data ready

100 = character timeout

001 = Tx Holding Reg empty

000 = modem-status change

lowest

1 = No UART interrupts are pending

0 = At least one UART interrupt is pending

an interrupt service routine
An interrupt service routine
  • Whenever the UART receives a new byte of data, it will transmit it back to the sender

#include <linux/interrupt.h>

#include <asm/io.h>

#define UART_BASE 0x03F8

irqreturn_t my_uart_isr( int irq, void *dev_id )

{

int intr_identify = inb( UART_BASE + 2 ) & 0x0F;

if ( intr_identify == 0x01 ) return IRQ_NONE;

if ( intr_identify == 0x04 ) // a new character has arrived

outb( inb( UART_BASE ), UART_BASE );

return IRQ_HANDLED;

}

installing the isr
Installing the ‘isr()’
  • Here is how your module asks the kernel to execute your UART interrupt-handler:

#define UART_IRQ 4 // signal-line’s number to the IO-APIC

char modname[] = “uartintr”; // kernel displays this in ‘/proc/interrupts’

static int __init my_init( void )

{

if ( request_irq( UART_IRQ, &my_uart_isr, IRQF_SHARED,

modname, &modname ) < 0 ) return –EBUSY;

// your code to enable the UART’s interrupts goes here

return 0; // SUCCESS

}

slide12

Interrupt Enable Register

7 6 5 4 3 2 1 0

0

0

0

0

Modem

Status

change

Rx Line

Status

change

THR

is

empty

Received

data is

available

If enabled (by setting the bit to 1),

the UART will generate an interrupt:

(bit 3) whenever modem status changes

(bit 2) whenever a receive-error is detected

(bit 1) whenever the transmit-buffer is empty

(bit 0) whenever the receive-buffer is nonempty

Also, in FIFO mode, a ‘timeout’ interrupt will be generated if neither

FIFO has been ‘serviced’ for at least four character-clock times

slide13

FIFO Control Register

7 6 5 4 3 2 1 0

RCVR FIFO

trigger-level

reserved

reserved

DMA

Mode

select

XMIT

FIFO

reset

RCVR

FIFO

reset

FIFO

enable

00 = 1 byte

01 = 4 bytes

10 = 8 bytes

11 = 14 bytes

NOTE: DMA is unsupported

for the UART on our systems

Writing 1 empties the FIFO, writing 0 has no effect

Writing 0 will disable the UART’s FIFO-mode, writing 1 will enable FIFO-mode

slide14

Modem Control Register

7 6 5 4 3 2 1 0

0

0

0

LOOP

BACK

OUT2

OUT1

RTS

DTR

Legend:

DTR = Data Terminal Ready (1=yes, 0=no)

RTS = Request To Send (1=yes, 0=no)

OUT1 = not used (except in loopback mode)

OUT2 = enables the UART to issue interrupts

LOOPBACK-mode (1=enabled, 0=disabled)

uart initialization
UART initialization
  • Here is code that initializes the UART (its baud-rate and data-format) and enables it to generate ‘character received’ interrupts:

// initialize the UART device for the desired demo operations

outb( 0x01, UART_BASE + 1 ); // issue RDR interrupts

outb( 0x00, UART_BASE + 2 ); // turn off FIFO-mode

outb( 0x80, UART_BASE + 3 ); // SET DLAB=1

outw( 0x0001, UART_BASE ); // DIVISOR_LATCH = 1

outb( 0x03, UART_BASE + 3 ); // data-format is 8-N-1

outb( 0x0B, UART_BASE + 4 ); // DSR=1, RTS=1, OUT2=1

disabling uart interrupts
Disabling UART interrupts
  • Here is code that disables any more UART interrupts, so that your module’s ‘cleanup’ can safely remove your interrupt-handler:

static __exit my_exit( void )

{

// disable any further UART interrupt-requests

outb( 0x00, UART_BASE + 1 ); // INTERRUPT_ENABLE

outb( 0x00, UART_BASE + 4 ); // MODEM_CONTROL

// remove your UART interrupt-service routine

free_irq( UART_IRQ, modname );

}

in class exercise
In-class exercise
  • Try running our ‘trycable.cpp’ application on an adjacent workstation after you have downloaded, compiled, and installed our ‘uartintr.c’ demo-module
  • What do you see on the two screens?
  • Tonight’s class ends early -- so that you can attend the ACM Chapter’s Pizza Night