The UART alternative - PowerPoint PPT Presentation

About This Presentation
Title:

The UART alternative

Description:

Last time we saw how the x86's trap-flag and debug-breakpoint ... This would spoil our kb2cable' application. read()' causes blocking' kb2cable' application ... – PowerPoint PPT presentation

Number of Views:124
Avg rating:3.0/5.0
Slides: 32
Provided by: cru6
Category:

less

Transcript and Presenter's Notes

Title: The UART alternative


1
The UART alternative
  • Substituting input from our PCs serial-port for
    local keystrokes when we do single-stepping

2
Problem background
  • Last time we saw how the x86s trap-flag and
    debug-breakpoint registers could be used to
    support single-stepping through program-code,
    to help us diagnose bugs
  • But a conflict arises when we attempt to debug
    code that handles keyboard-input (as in the
    isrKBD routine for Project 2)
  • Our debugger also uses keyboard input!

3
Use another control device?
  • To circumvent the contention for keyboard
    control, we ask can some other peripheral device
    substitute for our PCs keyboard as a convenient
    debugger-input source?
  • Our classroom and CS Lab machines offer us a way
    to utilize their serial ports as an alternative
    device-interface for doing this type of debugger
    single-stepping task

4
Kudlick Classroom
08
09
10
15
16
17
18
19
20
28
29
30
04
05
06
07
11
12
13
14
24
25
26
27
01
02
03
21
22
23
lectern
Indicates a null-modem PC-to-PC serial cable
connection
5
PC-to-PC communications
student workstation
student workstation
KVM cable
KVM cable
rackmount PC system
rackmount PC system
null-modem serial cable
ethernet cables
6
Using echo and cat
  • Our device-driver module (named uart.c) is
    intended to allow unprivileged programs that are
    running on a pair of adjacent PCs to communicate
    via a null-modem cable

Receiving
Transmitting
echo Hello gt /dev/uart _
cat /dev/uart Hello _
7
Instructions in isrDBG
  • Our usedebug.s used these instructions to
    support user-control of single-stepping

isrDBG .code32 Our trap-handler for Debug
Exceptions (interrupt-0x01) now await the
release of a users keypress kbwait in 0x64,
al poll keyboard-controller status test 0x01,
al a new scancode has arrived? jz kbwait
no, continue polling controller in 0x60, al
else input the new scancode test 0x80, al
was it a key being released? jz kbwait no,
wait for a keypress break
8
UARTs line-status
  • The PCs 16550 serial-UART interface has a
    status port and a data port that behave in a
    manner thats similar to those ports in the
    keyboard controller, so we can replace
    instructions in our isrDBG procedure that
    accessed keyboard-controller ports with
    instructions that access the UARTs ports
  • This avoids contention for the keyboard!

9
How to program the UART?
  • Universal Asynchronous Receiver-Transmitter
  • Software controls the UARTs operations by
    accessing several registers, using the x86
    processors in and out instructions

See our CS630 course website at
lthttp//cs.usfca.edu/cruse/cs630f08gt for links
to the UART manufacturers documentation and to
an in-depth online programming tutorial
10
The 16550 UART registers
Divisor Latch Register
Base0
16-bits (R/W)
Transmit Data Register
Base0
8-bits (Write-only)
Received Data Register
Base0
8-bits (Read-only)
Interrupt Enable Register
Base1
8-bits (Read/Write)
Interrupt Identification Register
Base2
8-bits (Read-only)
FIFO Control Register
Base2
8-bits (Write-only)
Line Control Register
Base3
8-bits (Read/Write)
Modem Control Register
Base4
8-bits (Read/Write)
Line Status Register
Base5
8-bits (Read-only)
Modem Status Register
Base6
8-bits (Read-only)
Scratch Pad Register
Base7
8-bits (Read/Write)
11
UARTs I/O-port interface
The PC uses eight consecutive I/O-ports to access
the UARTs registers
0x03F8 0x03F9 0x03FA 0x03FB
0x03FC 0x03FD 0x03FE 0x03FF
RxD/TxD
IER
IIR/FCR
LCR
MCR
LSR
MSR
SCR
modem status register
line status register
interrupt enable register
modem control register
line control register
scratchpad register
receive buffer register and transmitter holding
register (also Divisor Latch register)
interrupt identification register
and FIFO control register
12
Comparing STATUS ports
Keyboard-controllers status-register (i/o-port
0x64)
7 6 5 4
3 2 1 0
Parity error
Timeout error
Data is from Mouse
Keyboard locked
Last byte went to 0x64
System initialized
Input Buffer Full
Output Buffer Full
Serial-UARTs line-status register (i/o-port
0x03FD)
7 6 5 4
3 2 1 0
Error in Rx FIFO
Transmitter idle
THR empty
Break interrupt
Framing error
Parity error
Overrun error
Received Data Ready
13
Changes to isrDBG
keyboard controls single-stepping
serial-UART controls single-stepping
isrDBG kbwait poll for OUTB1 in 0x64,
al test 0x01, al jz kbwait input new
scancode in 0x60, al ignore make
codes test 0x80, al jz kbwait
isrDBG inwait poll for RDR1 mov 0x03FD,
dx in dx, al test 0x01, al jz inwait
input new data-byte mov 0x03F8, dx in dx,
al send back a reply mov ,
al out al, dx
14
Using a Linux application
  • To control our debugger from another PC, weve
    written an application-program that runs under
    Linux, and it uses our uart.c device-driver to
    circumvent privilege-level restrictions that
    Linux imposes on access to i/o-ports by code
    which runs in ring3
  • Our application is named kb2cable.cpp
  • It also illustrates use of i/o multiplexing

15
Linux Kernel Modules
Linux allows us to write our own
installable kernel modules and add them to a
running system
Runs in ring3
application
Runs in ring0
device-driver module
call
ret
ret
call
syscall
standard runtime libraries
Operating System kernel
sysret
user space
kernel space
16
Linux char-driver components
Device-driver LKM layout
modules payload is a collection of
callback-functions having prescribed
prototypes
function
function
function
AND a package of
function-pointers
fops
. . .
init
the usual pair of module-administration
functions
registers the fops
exit
unregisters the fops
17
write() and read()
  • Obviously your driver-modules payload will
    have to include methods (functions) which
    perform the write() and read() operations
    that applications will invoke
  • You may decide your driver needs also to
    implement certain additional methods
  • For example, to support i/o multiplexing our
    driver needed to implement poll()

18
UART initialization
  • For two PCs to communicate via the serial
    null-modem cable, their UARTs must be configured
    to use identical baudrates and data-formats
    (i.e., 115200 bps, 8-N-1)
  • Our uart.c driver performs this essential
    configuration in its module_init() function
  • Our remotedb.s application does it in an extra
    real-mode subroutine weve added

19
The sequence of steps
(steps are described below in pseudo-code)
initializing the UART communication parameters
for 115200 bps, 8-N-1 outb 0x00, UART_BASE1
Interrupt Enable register outb 0xC7,
UART_BASE2 FIFO Control register outb 0x83,
UART_BASE3 Line Control (DLAB1) outw 0x0001,
UART_BASE0 Divisor Latch register outb 0x03,
UART_BASE3 Line Control (DLAB0) outb 0x03,
UART_BASE4 Modem Control l inb UART_BASE6
Modem Status inb UART_BASE5 Line
Status inb UART_BASE0 Received
Data inb UART_BASE2 Interrupt Identification
20
The i/o-multiplexing problem
  • Normally when an application reads from a
    device-file, that process will sleep until some
    data is available from that device
  • So if data becomes available on another device,
    it will not get processed because the application
    is blocked from being given any CPU time by the
    OS scheduler
  • This would spoil our kb2cable application

21
read() causes blocking
kb2cable application
Keyboard
Serial UART
read
write
read
write
Whichever device this application attempts to
read from, it will get blocked until that
device has some data to deliver
22
Do multiprocessing?
  • One idea for getting around this blocking
    problem would be to just use the fork()
    system-call to create separate processes for
    reading from the different device-files
  • Each process can sleep, and whichever process
    receives any new data will be awakened and
    scheduled for execution
  • No changes needed to device-driver code

23
Different processes do read()
kb2cable parent- process
write
read
Keyboard
Serial UART
kb2cable child-process
read
write
Using multiple processes can overcome the
blocking-read problem, but complicates the
code for program termination
24
Non-blocking read
  • It is possible for the application to request
    non-blocking read-operations i.e., any
    read() calls will immediately return with 0 as
    return-value in case no data is available
  • The standard-input device-driver already has
    support for this non-blocking option, and it can
    be easily added to the read() function in our
    serial UARTs device driver

25
Driver-code modification
ssize_t my_read( struct file file, char buf,
size_t len, loff_t pos ) static int rxhead
0 // in case no new data has been received,
then either // return immediately if
non-blocking mode is in effect // or else sleep
until some new data arrives (or until // the
user hits ltCONTROLgt-C to cancel execution) if
( rxhead ioread32( io E1000_RDH ) if (
file-gtf_flags O_NONBLOCK ) return 0 if (
wait_event_interruptible( wq_recv, inb(
UART_LINE_STATUS ) 0x01 ) return
EINTR
26
Uses busy-waiting loop
kb2cable application
Keyboard
read
write
Serial UART
write
read
Using the nonblocking-read option overcomes
the problem of a sleeping task, but it
wastefully consumes the CPU time
27
The elegant solution
  • The select() system-call provides a very
    general scheme for doing i/o-multiplexing in a
    manner that avoids wasting CPU time or making the
    program-code complicated
  • But it does require adding an extra driver
    method the so-called poll() function

28
The select() arguments
  • Using select() requires an application to setup
    an fd_set object, which defines the set of
    file-descriptors whose activity needs to be
    monitored by the Linux kernel (in our kb2cable
    application this would be just the two
    device-files handles (the keyboard and the
    serial UART)
  • This fd_set object becomes an argument

29
Using select() in kb2cable
int kbd STDIN_FILENO // keyboard ID
int uart open( /dev/uart, O_RDWR ) //
device-file ID fd_set permset // create an
fd_set object FD_ZERO( permset ) //
initialize it to empty FD_SET( kbd, permset
) // add keyboard to set FD_SET( uart,
permset ) // and add the nic to set while
(1) fd_set readset permset if ( select(
1uart, readset, NULL, NULL, NULL ) lt 0 )
break if ( FD_ISSET( kbd, readset ) ) /
process keyboard input / if ( FD_ISSET(
uart, readset ) ) / process network input /

30
How it works
  • The readset argument to the select()
    system-call lets the kernel know which
    device-drivers should have their poll() method
    invoked
  • Then each device-drivers poll() method will
    perform a test to determine if any new data is
    ready to be read from that device
  • So the application calls read() only when a
    device is ready with data immediately!

31
In-class demo
  • As a proof-of-concept demonstration, we adding a
    trivial Interrupt Service Routine for keyboard
    interrupts to our remotedb.s program (we called
    it addkbisr.s)
  • Then we used our kb2cable application running
    on an adjacent Linux machine to do
    single-stepping through linuxapp.o -- and
    through the added isrKBD handler
Write a Comment
User Comments (0)
About PowerShow.com