Hardware abstraction layers

I feel as though I have been spending most of my CORNELIUS efforts on the ELIUS (language) part, and neglecting the CORN (operating system) part.

Recently, though, I have been thinking about the notion of a "hardware abstraction layer" (HAL). This is a common part of many systems, and serves to isolate the messy, hardware-specific details from the core functionality of the OS (memory management, process management, etc.) For most systems this is a good thing. If we had to build or download a whole new OS for every small hardware change nothing would ever get done. Typical PC boxes have a huge range of possible components, processors, storage, network and display cards, and so on. Even apparently simple things such as keyboards and mice come in a multitude of variants.

The point of the HAL on a PC is to present a common, often simplified, abstraction for each "class" of device, which the core code can use. This can easily be seen on The Raspberry Pi running Linux. Files appear like serial character streams, processes appear like files, SD cards appear like hard disc drives and so on.

A hardware-oriented platform such as the Raspberry Pi is another thing altogether. The core hardware is pretty much the same for everyone (barring minor issues of board revisions and such), but what varies is the wild and unpredictable range of external hardware which users are encouraged to plug in and do stuff with. Attempting to model new, unknown, devices as if they are somehow the same as something the system already knows about often leads to an over-simplified, or even broken model.

As Charles Moore points out:

Don't try for platform portability. Most platform differences concern hardware interfaces. These are intrinsically different. Any attempt to make them appear the same achieves the lowest common denominator. That is, ignores the features that made the hardware attractive in the first place.

Achieve portability by factoring out code that is identical. Accept that different systems will be different.

This is a challenging point of view, and goes some way to explain my unease with abstraction layers such as WiringPi. Don't get me wrong. WiringPi is very clever and very useful. My concern, though, is that although implicitly modelling the Raspberry Pi as if it is an Arduino makes some things much easier (soft PWM, for example), it leads to a very sharp disconnect between things that WiringPi will do for you, and things that you need to do for yourself or, worse, things that the abstractions in WiringPi get in the way of doing.

At the moment I'm considering a different kind of approach which, rather than starting with a model of the built-in hardware, starts with individual models of I/O types, and allows the user to associate these I/O types to different memory locations and interfaces. My aim is that this will allow for a system configuration which can model both the similarities and differences of built-in and plugged-in devices.

For example, one of the simplest concepts is that of an output pin. The Basic Pi hardware provides several, but so do other devices such as the < ahref="http://openmicros.org/index.php/articles/94-ciseco-product-documentation/raspberry-pi/223-slice-of-pio">Slice of PI/O, which provide I/O pins with similar capabilities but which need to be addressed in a completely different way..

The kind of HAL I hope to build will allow a user to tell the system the details of the additional hardware (in this case 16 I/O pins addressed using 12c), give the pins names (or some other unique ids) and then allow the user to use the same basic "output pin" operations on these new pins, but also to use a set of basic "i2c" operations if that makes more sense.

At the moment I'm not quite sure what form this HAL might take (or even if it is possible in the form I envisage) but it is my hope that this approach will lead to application code which is "portable" in a good sense. Such as allowing my trusty morse code example to be usable on both built-in (OK-LED), directly attached (LEDBorg), or indirect (a lamp attached to one of the Slice of PI/O pins, or controlled by a PiFace) without changing the logic, but just telling it which "output pin" to use.

Leave a Reply

Your email address will not be published. Required fields are marked *