So far in Tech Tuesday we have taken a first look at how a computer does its work (processor), where it keeps data for quick access (memory), where data is kept longer term (storage) and how computers talk to each other (networking). Today’s topic is how to get data in and out of computers and to and from such things as printers, keyboards, screens, sensors, and more. These things are usually referred to as devices or peripherals. In the early days of computing many peripherals were relatively simple with early printers being not that different from typewriters (and the teletype combining keyboard input with printer output). These days when you buy a laser printer, you are really picking up a computer with its own CPU and memory! Still the basic problems of input/output have remained roughly the same.
For all peripherals there is a cabling and data transmission problem that’s similar to the one encountered in networking. There too I punted on this physical layer and I will do the same here. Suffice it to say that’s where things like USB (Universal Serial Bus) and HDMI (High Definition Multimedia Interface) come into play. I may cover these in more detail at some future point as they do contain a fair bit of complexity. For now, though I want to focus on two different problems related to devices that are critically important to understanding how computing works and has evolved: interrupts and queues. I will work through these in the context of a keyboard and a printer but the issues apply equally with other devices (including as it turns out the disks used in storage, which are really just another device albeit one so important that they got their own post and will get more posts in the future).
What’s going on inside the computer as I am typing this post? More specifically what happens when I press a key on the keyboard? Not surprisingly, each key is associated with a binary code for that key. When I press the key, the code for that key is written into a memory location known as the keyboard buffer. But as we have previously learned, memory itself is lazy, so how does the key code get there and how does the CPU know that a new value has been delivered by the keyboard? That’s where a so-called “interrupt” comes into play. The keyboard device triggers an interrupt when a key is pressed. That interrupt tells the CPU to stop what it is doing and jump to a different program — a program for handling keyboard input. That program usually does nothing other than read the code of the pressed key and write it into the keyboard buffer keeping track of which buffer location it is currently at an incrementing that location so that the next key that is pressed doesn’t overwrite the value of the previous key if that has not yet been made use of. The program that does all of that is known as the keyboard driver and is part of a computer’s operating system.
Now the keyboard buffer that I just described is really just a special example of something known as queue. Just like the people queue that forms at an ATM machine or an airline check in counter every new keyboard code that arrives lines up behind the ones that have arrived before. When writing output to a device the computer similarly uses queues. Let’s say I print this post to a printer. The computer will first write the output to a printer queue — an area in memory from where it will be transferred in portions to the printer (in the early days that happened literally byte-by-byte). Unlike “interrupt”, the word “queue” has made it into the visible user interface of most computer operating systems. There is usually some option to view which documents are in the print queue. Why does the computer need these queues? Well, if the CPU were not able to write output to a queue and have the printer driver take it from there, the CPU would not be able to do a lot of useful things while waiting for the printer. Of course the printer is much much slower than the CPU, especially when someone has forgotten to reload the paper! With the output in the queue, the CPU can be available to do useful stuff and whenever the printer needs a bit more data to print an interrupt causes the printer driver to be run. As in the case of the keyboard driver this is a low level program that just picks up some more bytes from the queue and sends them over to the printer.
So the key takeaway here is: computers use queues and interrupts to decouple peripheral devices from the CPU. The programs managing these queues and responding to the interrupts are the so-called device drivers. Both of these make for interesting challenges. What happens to whatever program that was executing when the interrupt occurred? What should the computer do when a queue is full but the device provides more input or the user tries to send more output to the device? Lots to cover in upcoming Tech Tuesdays, including a fair bit of interesting history around the licensing for device drivers and epic fights between makers of computers and peripherals.
P.S. Having now covered each of the basic building blocks at least once, I am open to suggestions where to go next. I was thinking about introducing the idea of programming and assembly language.