[ Class Overview ] [ PIC ]
Task 2: Interrupt handling for OOStuBS
Learning objectives
- Handling of asynchronous events
- Issues and protection of critical sections
Task description
A simple interrupt handling for the interrupts by the keyboard should be implemented.
To achieve this, the classes PIC, Plugbox, Gate, Panic, Keyboard as well as the function guardian have to be implemented. The class CPU is included in the specification.
In order to use the corresponding devices everywhere in OOStuBS, global objects cpu, plugbox, pic and keyboard should be created from the classes CPU, plugbox, PIC and keyboard.
Implementation notes
Part a
In the first step the class PIC should be implemented. With its help and with the help of the class CPU interrupts from the keyboard can be allowed (during the boot process all interrupts were masked out at the CPU and the PIC). If 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 in guardian(), part a can easily be tested – at least a few times. If the characters are not fetched by the keyboard controller, the keyboard buffer will eventually run full. However, as soon as the buffer is full, the keyboard controller stops sending interrupts. Therefore it can happen that you get interrupts for only 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 assembly
instruction
iretq
. This corresponds to the last closing bracket of theguardian()
implementation: initializing the vector table instartup.asm
ensures that it is 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, an infrastructure is created 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
The Keyboard class should be implemented here. It represents the actual keyboard driver. The interrupts that the keyboard triggers must be caught and interpreted. After every key press, the corresponding character should be displayed at a fixed position on the screen. 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 doesn't 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(). It is supposed to make outputs in an endless loop at a fixed position. It should now be possible to "mess up" the output by pressing keys. Think about what is happening when you do this and avoid the problem by using the functions of the CPU class.
Specification
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)