A detailed description
of this Qt component can be given under two different headings
1.
qpu_irq_reporter kernel
module.
2. QpuInterruptHandler Qt classe
qpu_irq_reporter kernel module.
This module consits of
functions that make up the qpu_irq_reporter device driver. The module
offers two things
A character device
driver for user programs to register and unregister IRQs whose
occurances they want reported
An interrupt handler that records IRQ occurances
Here is a brief introduction
to the concepts in the device driver
IRQ Occurance
IRQ occurance is a
description of what IRQ occured and at what time. qpu_irq_reporter
stores IRQ occurances in a structure called qpu_irq_occurance. The
structure is pasted below for reference
struct qpu_irq_occurance { int irq; unsigned long jiff_val;};
As you can notice; the structure stores the IRQ number and the value of
jiffes when the IRQ occured.
IRQ
Occurance Stack
IRQ Occurance Stack; as the
name explains; is a stack of qpu_irq_occurance objects. The stack is
stored as a linked list and is manipulated by making use of custom push
and pop methods. For more information on the structure used for the
stack and its manipulation methods; refer to the following functions.
qpu_irq_occurance_stack_node_t
qpu_irq_occurance_stack
push()
pop()
clear()
Two types of occurance stacks
are used in this driver; they are
Driver's Occurance
Stack or Global Occurance Stack
File's Occurance Stack
Global
Occurance Stack
The interrupt handler (
qpu_irq_reporter_handler() ) when called, obviously because an IRQ
occured, records the IRQ occurance into a qpu_irq_reporter variable and
pushes it on to the global occurance stack. After doing so it schedules
a tasklet for further processing the occurance.
File's
Occurance Stack
The file object representing
open files on this device has a private_data pointer. This pointer is
set to point to a structure instance of type
qpu_irq_file_private_data_t. This structure instance contains two
pieces of information
The IRQs that the
process (that has opened the file) is interested in having reported
A IRQ Occurance Stack that contains occurances of interest
for that particular file.
All the files (pointer to
file objects) opened on this driver are stored in a linked list
file_list. This linked list is updated by the open() and release()
methods in file_operations interface; more specifically by the
qpu_irq_reporter_open() and qpu_irq_reporter_release() methods.
The tasklet scheduled by the
interrupt handler ( qpu_irq_reporter_handler() ) does this
while(
global_irq_occ_stack_has_occurances ) { irq_occurance =
pop(global_irq_occ_stack); for_each_file_in(file_list) { if(file is
interested in the current occurance) push(irq_occurance,
file_irq_occ_stack); } }
Character
Device Driver Interface
This module provides a
character device driver by name qpu_irq_reporter. The major number of
this device is dynamically requsted. You may find out the major number
by using the following command
[root@localhost $] cat
/proc/devices | grep "qpu_irq_reporter"
qpu_irq_reporter provides
an ioctl() system
call interface to register, unregister and to count the number of IRQ
occurances registered for a given file. It also provides a command for
querying the value of NR_IRQS #define.
a read() system call interface to read IRQ occurances for a
file.
a select() system call interface to synchronously poll for
read events. This way user programs can synchronously figure out if any
IRQ occurances are waiting to be read. This is made use of by the
QpuInterruptHandler class.
The following table
summarizes the ioctl() commands supported by qpu_irq_reporter device
| Command |
Description
|
| REGISTER_IRQ |
Register a new IRQ for
occurance reporting |
| UNREGISTER_IRQ |
Unregister a IRQ for
occurance reporting |
| CHECK_IRQ |
Check if an IRQ has
been requested for reporting |
| IRQ_OCC_COUNT |
Count the number of
occurances waiting to be read |
| IRQ_COUNT |
Fetch the value of
NR_IRQS |
The following points are
worth noting.
The ioctl()
implementation requests an IRQ in the REGISTER_IRQ command __iff__ the
IRQ was not already requested.
the ioctl()
implementation frees an IRQ in the UNREGISTER_IRQ command __iff__ no
file object is interested in the IRQ being unregistered.
Driver's file object list
Each time a file is opened;
the corresponding file structure is inserted into a list of file
objects opened on the file. When the file is closed; the corresponding
file structure is removed.
Note:
Actually just a pointer to the file structure is stored in this list.
This means that the "Driver's file object list" always contains a list
of file objects currently open on the driver.
QpuInterruptHandler class
This class forms the main
interface to qpu_irq_reporter device driver. This class is an abstract
class that should be subclassed to implement the handleIRQ() virtual
method.
Use the addIRQ()
and removeIRQ() methods to add/remove IRQ for receiving IRQ occurance
events.
Use the handlingIRQ() method to figure out whether a IRQ is
being handled by this class or not.
Use the irqCount() method to find out the number of IRQs
(NR_IRQS) supported by the kernel
Connect to the deviceNotLoaded() signal to receive a signal
when the class finds out that the qpu_irq_reporter device is not loaded
Connect to the deviceFault() signal to receive a signal
when any of operations initiated by this class results in an error.