There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.
—Shakespeare - "Hamlet"
In order to design an automatic discovery and configuration mechanism for popular small form factors like Arduino, rfDuino, LaunchPad, and others, we first need to decide on simple connection chain that can connect all the subsystems, one which is already included in each of these form factors. We need to be able to describe the heirarchy of devices, and the connections between them, in order to understand the topology of our embedded system.
The problem reminds me somewhat of that faced by the early philosophers in trying to understand their place in the hierarchy of the universe. Aristotle's History of Animals classified organisms in relation to a linear "ladder of life", or Scala Naturae, which allowed for an ordering of beings, from dirt at the bottom, to God at the very top, with all creatures occupying rungs of the ascending ladder between. The Great Chain of Being connected all things, as all things were linked together to form the universe in one solid, unbroken chain. By the time of the Renaissance, the concept of Great Chain of Being had become pervasive, used to justify the feudal system and the divine right of kings. Later still, this would influence poets such as Robert Blake to compose lines like, "As above, so below".
We also need to define a chain of physical entities, and the links that make up their interconnections. In reality, we will need to define several, as some may be connected only by wireless linkages, but for this introduction, we will discuss only the physically connected entities, such as an Ardunio Shield, rfDuino, Launchpad, and the like.
The simplest and most ubiquitous interface found on all of these platforms is I2C, or the Inter-Integrated Circuit bus. Also known as the "Two-Wire Bus" or TWB, I2C is found on almost every embedded platform, and can be easily implemented with software bit banging on general purpose I/O pins (GPIO), if a hardware interface block is not readily available. In addition, the MIPI Alliance is in the final stages of the ratification process for the new SenseWire/I3C Sensor Interface Specification; I3C defines a much higher performance interface, capable of supporting many more high speed sensors than the original I2C bus specification.
I2C is a good choice for this purpose, as it is both commonly available, and also supports the very low cost I2C EEPROMs that we will need for our configuration storage. An example implementation of this automatic configuration scheme would resemble the diagram below :
Typical I2C EEPROMs employ a three(3) bit hardware selection mechanism, allowing up to eight(8) devices to share the same I2C bus. In communicating with the I2C EEPROMs, the first byte sent is the control word, which serves to select which one of the eight(8) devices will respond to the read/write operation on the shared I2C bus.
Using this addressing scheme, we can support up to eight(8) levels of devices in our stack, which should be
adequate for most purposes. The standard addressing for each level is shown in the table below :
A2 | A1 | A0 | I2C Address | Device |
0 | 0 | 0 | 0x50 | Chassis (Power Supply) |
0 | 0 | 1 | 0x51 | Boot Processor #0 (Arduino, BeagleBone) |
0 | 1 | 0 | 0x52 | CoProcessor #1 (Logger) |
0 | 1 | 1 | 0x53 | CoProcessor #2 (Logic Analyzer) |
1 | 0 | 0 | 0x54 | Shield #1 (Beaglebone Cape #1) |
1 | 0 | 1 | 0x55 | Shield #2 (Beaglebone Cape #2) |
1 | 1 | 0 | 0x56 | Shield #3 (Beaglebone Cape #3) |
1 | 1 | 1 | 0x57 | Shield #4 (Beaglebone Cape #4) |
You'll notice that the Arduino (or Launchpad, etc.) is not at the very bottom of the stack, as there may be a chassis or other lower level that the stack is mounted within, in order to provide battery or solar power to the system. We may need to be able to interogate that level to inquire how much power is available, or inquire about other parameters. In later articles, I'll outline some other uses for the lowest level, such as instrumentation, testing, and monitoring of the system.
So, what about more than eight(8) levels you might be asking? What then? Well, the I2C bus has some physical loading limitations, that have to do with the larger bus capacitances that result when you extend the bus too far, or add too many loads(devices). In practice, there may need to be I2C bus buffers, repeaters, hubs, or multiplexors employed to keep each segment of the I2C bus within specified loading limits. However, the addressing scheme above would apply to each separate segment of a larger system, although you may need to address a multiplexor or hub first to select a particular segment to read or write.
You might also notice that the Beaglebone "Capes" (the name for their expansion boards) are limited to four(4) "Capes", this is a specific limitation of the Beaglebone.
We now have a basic outline for a hardware design pattern for automatic discovery and automatic configuration using simple I2C interfaced EEPROM memory chips. The next step is to define the data structure within each of the I2C EEPROMs shown, and how that data structure defines the components and topology of the overall system. The next article will cover currently available data structures like the Device Tree and IPMI formats.