Last time, we started designing a primitive keyboard. It consisted primarily of a collection of switches (one for each key). These are connected to an encoder; when a key is pressed, a collection of wires encoding the key code is activated.
In fact, the keyboard probably needs a bit more logic, for example to store the key that was pressed so that it can be accessed in the future. Terminology: the hardware in a device that operates the device (and communicates with the main CPU) is the device controller. It can be as simple as a few gates and a latch (as with the keyboard) or as complex as the CPU itself (in the case of a modern GPU)
The interesting question is what happens next. What do we do with those signals? How do they make their way to the processor and ultimately the program?
One design question is HOW the program interacts with the device:
Our first idea was to have a dedicated I/O bus. The keyboard (and other devices) are connected to the bus. The instruction set has dedicated instructions for interfacing with this bus. This design is called programmed I/O.
Our second idea (and one that is more commonly used) is to connect the devices directly to the memory bus. Each device has a specific range of physical addresses allocated to it; the address lines of the bus determine whether the data and r/w lines are connected to main memory or to the device. To read data from the keyboard, the processor issues a read instruction to the address corresponding to the keyboard. This scheme is called memory mapped I/O because the device is mapped into the physical address space. Note that there is not any physical memory corresponding to the memory mapped addresses.
For devices that manipulate a lot of data (such as a camera, microphone, or graphics card), it makes sense to allow the devices to communicate directly with main memory. This is referred to as direct memory access (DMA). In this approach, the program would use memory-mapped I/O to control the device, but then the device could transfer data to or from physical memory. It would then notify the processor (with an interrupt) when the transfer is complete.
Another question is WHEN the program interacts with the device:
One option is to have the CPU continually monitor the device to see if any input has occurred. This is called polling and is almost always a bad idea. The primary reason is that the CPU must waste a lot of effort rechecking the device. Also, if it does other work inbetween checks, it may miss events or respond to them with a large delay.
Another option is to have the device interrupt the CPU, causing it to jump to an interrupt handler routine: a piece of code that interacts with the device (using I/O instructions for programmed I/O or loads and stores for memory-mapped I/O). The mapping from devices to interrupt handlers is called the interrupt vector; it is part of the interrupt controller. Interrupts require special instructions to update the interrupt vector, and to mask and prioritize interrupts.
The obvious remaining question when doing I/O is what to do while waiting. I/O can take millions of cycles, and sitting around waiting is a large waste of resources.
A natural choice is to have several tasks available, and to switch to a different task while waiting for input.
Some terminology:
A program is the code defining an executable. It can be stored in a file, loaded into memory, downloaded from the internet.
A process is a running program. In addition to the code, it has state: the values of registers, and a virtual address space. If you run a program twice, you will create two processes (but there will only be one program).
application is a fuzzy term that I will use when I don't want to make a distinction.
When a process wants to wait for I/O, it calls a scheduler, which looks at the list of available processes and selects the next one to run. When the input becomes available, the interrupt handler can then schedule the process that was waiting to be run in the future.
Next lecture, we will talk about context switching from one process to another, and how to make scheduling decisions.