Title: On using
1On using tasklets
- An example of the Linux kernels tasklet
mechanism for deferring some interrupt-handling
work
2Recall purpose of Project 2
- Allow you to gain experience encountering the
kinds of issues that commonly arise in crafting
software to operate real hardware - Learning the hardware devices capabilities
- Deciding which driver-methods to implement
- Accommodating your platforms interfaces
- Exploiting the OS kernels support-functions
- Devising a strategy for testing and debugging
3Driver enhancements
- Now that youve had an opportunity to get
acquainted with the NS16550 serial UART (its
documented capabilities and its quirks) we can
build upon what you experienced to contemplate
software enhancements that might not have made
much sense if you lacked any actual confrontation
with real-world peripheral hardware on PCs
4Urgent versus non-urgent
- When some peripheral device issues an interrupt
request, it may need a prompt response to handle
an urgent situation - After the emergency has been dealt with, there
may also be some further actions which are
necessary, but which can be safely delayed
without jeopardizing the integrity of proper
system functioning
5The serial UART
- As an example, when the UART receives characters
via its serial-port, there is only a limited
capability for preserving them in the devices
on-board receive buffer - These received characters need to be quickly
moved out of the UART before they get overwritten
by newer data -- or before they can cause other
incoming characters to be lost for lack of space
6The handshake lines
- A device-driver for the UART can use the
handshaking signal-lines to regulate the quantity
of data being transmitted to it - It can de-assert the Clear-To-Send signal being
sampled by its equipment partner as a way to
temporarily pause data-transfers - Once the incoming data-stream is paused, there is
less urgency to move data aside
79-wire null-modem cable
CD
CD
RxD
RxD
TxD
TxD
GND
GND
DSR
DSR
DTR
DTR
RTS
RTS
CTS
CTS
RI
RI
Data Terminal Equipment
Data Terminal Equipment
the sender
the receiver
8Modem Control Register
7 6 5 4
3 2 1 0
0
0
0
LOOP BACK
OUT2
OUT1
RTS
DTR
The receiver clears this bit
Legend DTR Data Terminal Ready (1yes,
0no) RTS Request To Send (1yes, 0no)
OUT1 not used (except in loopback mode)
OUT2 enables the UART to issue interrupts
LOOPBACK-mode (1enabled, 0disabled)
9Modem Status Register
The sender checks this bit
7 6 5 4
3 2 1 0
DCD
RI
DSR
CTS
delta DCD
delta RI
delta DSR
delta CTS
set if the corresponding bit has changed since
the last time this register was read
Legend ---- loopback-mode ---- CTS
Clear To Send (1yes, 0no) bit 0 in Modem
Control DSR Data Set Ready (1yes, 0no)
bit 1 in Modem Control RI Ring
Indicator (1yes,0no) bit 2 in Modem Control
DCD Data Carrier Detected (1yes,0no) bit 3
in Modem Control
10The senders algorithm
Set RTS1 in the Modem Control Register
Read the Modem Status Register
CTS1?
NO
YES
Read the Line Status Register
THRE1?
NO
YES
Write byte to the Transmit Data Register
DONE
11The receivers actions
- When the receivers storage capacity has been
reached, it takes urgent action to pause any
further transfers of data (i.e., it writes 0
to the RTS-bit in its Modem Control register) - Then it needs to remove its accumulation of
received data out of its storage medium - Being less urgent this can be postponed
12Interrupt handling
- Often its beneficial to separate the actions a
driver performs in responding to a device
interrupt-request into two categories the urgent
ones are performed immediately, the less urgent
ones temporarily delayed - Accordingly programmers write separate functions,
known as the top half and the bottom half for
an interrupt handler
13Application to the UART
- Top Half
- Tell sender to pause further data-transfers
- Bottom-Half
- Move accumulated data out of the devices
on-board storage-area (e.g., its receive FIFO)
14A tasklet for bottom half work
- Your device-driver allocates and initializes a
struct tasklet_struct object, possessing a
name, a function and a pointer to data - Your drivers top-half interrupt-handler will
schedule your tasklet for future execution
name
function
struct tasklet_struct object
data-pointer
15Linux syntax
- include ltlinux/interrupt.hgt
- struct tasklet_struct my_tasklet
- struct mydata my_tasklet_data
- void my_function ( unsigned long )
- tasklet_init( my_tasklet, my_function,
(unsigned long)my_tasklet_data ) - tasklet_schedule( my_tasklet )
- tasklet_kill( my_tasklet )
16Tasklet semantics
- A few technical points to keep in mind if you
decide to make use of tasklets - A tasklet runs at interrupt time (so it
doesnt own any user-space context, just
kernel-space context)
The kernel-space context is consistent
across all tasks
kernel space
user space
Some interrupted tasks context resides
here (so it cant be predicted)
virtual memory
17More tasklet semantics
- A tasklet runs in atomic mode (so cannot
sleep), although it can wake up a task that is
sleeping - A tasklet executes on the CPU that scheduled it
(and so doesnt execute concurrently with itself) - You can schedule your tasklet to run either at
normal priority or at high priority the
latter ones all are run before any of the former
ones
18sleep versus busy waiting
- Our tasklet.c demo uses the interruptible
sleep mechanism in its device-driver read()
method - Whenever the UART receives new data, it will
interrupt whatever else the CPU is doing - Quickly our top half interrupt-handler pauses
any more data-transfers, schedules our bottom
half for future execution, then resumes the
interrupted task - Later our tasklet will move accumulated data
from the FIFO to a ringbuffer, then will awaken
any task was sleeping on our read functions
wait-queue
19The senario overview
READ() sleeps until drivers ringbuffer has
some data moves data from drivers ringbuffer
to users buffer issues Clear-To-Send if
case the drivers ringbuffer has been
emptied reports count of bytes returned in
users buffer
Arrival of new data interrupts the CPU
ISR stops the sending of additional data
schedules the tasklet resumes the Interrupted
task
TASKLET transfers received bytes from UART
to to ringbuffer wakes up sleeping readers
20write()
- We did not employ efficiency-techniques in our
device-drivers write() function - No wait-queues
- No interrupts
- No tasklets
- Thus there is still an opportunity for you to add
improvements to our tasklet.c demo!
21In-class exercise
- Download our tasklet.c module from the course
website, compile it, and install it a pair of our
machines which are connected to each other via a
null-modem cable - Try testing the robustness of our driver
First launch the cat command
then redirect lots of screen-output!
cat /dev/uart
ls -l /usr/bin gt /dev/uart