[ Class Overview ] [ PIC ]
Task 2: Interrupt handling for OOStuBS
Learning objectives
- Handling of asynchronous events
- Issues and protection of critical sections
Task description
In this task, you will implement simple interrupt handling for keyboard interrupts.
To achieve this, the classes PIC, Plugbox, Gate, Panic, Keyboard as well as the function guardian have to be implemented. Class CPU is included in the specification.
In order to use the corresponding devices everywhere in OOStuBS, you should instantiate the global objects cpu, plugbox, pic and keyboard from the classes CPU, plugbox, PIC and keyboard, respectively.
Implementation notes
Part a
In the first step, you should implement class PIC. With its help and with the help of class CPU, interrupts from the keyboard can be allowed (during the boot process all interrupts were masked out at the CPU and the PIC). Once this works, the guardian function should be automatically activated each time a key is pressed and released, since the interrupt vector table was initialized accordingly in the startup code. With an output inguardian()
, Part a can easily be
tested – at least a few times.
If the OS does not fetch/retrieve the scan and break codes from the keyboard
controller, the keyboard buffer will eventually fill up.
However, as soon as the buffer is full, the keyboard controller stops
triggering interrupts.
Therefore, expect to only get interrupts for one or two key presses at the
beginning.
Hints:
- During the handling of an interrupt you don't have to worry about
unwanted interrupts. This is because the processor automatically turns
them off when it starts handling them, and does not allow them again
until the interrupt handling is terminated with the
iretq
machine instruction. This corresponds to the last closing bracket of theguardian()
implementation: initializing the vector table instartup.asm
ensures that it is almost immediately followed by aniretq
. -
Of course, your interrupt handling can only work if OOStuBS is actually
running. As soon as OOStuBS leaves the
main()
function, the behavior is undefined when an interrupt occurs. An operating system should simply not end suddenly :-)
Part b
In the second step, you will create an infrastructure to pass the interrupt handling to an associated device-driver object. The Plugbox class, which provides a pointer to a Gate object for each possible interrupt, is used to manage driver objects. Gate is an abstract class that describes the interface of all interrupt-handling drivers. Initially, all pointers of the Plugbox are set to point to a global Panic object.
Part c
You should now implement the Keyboard class.
It represents the actual keyboard driver.
The interrupts the keyboard triggers must be caught and interpreted.
After every key press, display the corresponding character at a fixed
position on the screen using kout.setpos()
and the stream
operators you implemented in task 1.
Additionally, the key combination "Ctrl-Alt-Delete" should trigger a reboot.
At this point, you should also edit the Keyboard_Controller class again.
-
The function
key_hit
is now only called as a result of an interrupt. It must not wait actively for key presses anymore, but can directly read the status and data byte from the keyboard. Consider programming defensively here, i.e. somehow deal with the cases that a) an interrupt occurs but the keyboard buffer is empty or b) the buffer contains more than one byte. -
In the functions
set_led
andset_repeat_rate
you have to consider that also the ACK byte of the keyboard generates an interrupt – but this byte is used directly inset_led
orset_repeat_rate
and therefore should not trigger a CPU interrupt. If the PIC currently allows keyboard interrupts, they must be disabled for the duration of the function execution and then enabled again.
Part d
Write a test program in Application::action()
, which is called
from main()
.
This program should make outputs in an endless loop at a fixed position
(again, using kout.setpos()
and the kout
stream
operators).
It should now be possible to "mess up" the output by pressing keys.
Think about why this is the case, and avoid the problem by using functions of
the CPU class.
Template code
We have already implemented the CPU class for you. For the actual keyboard request you can reuse your Keyboard_Controller class from task 1.
Additional information
- Information about the Programmable Interrupt Controller (PIC)