In the early days, Linux was distributed in source form, or as a bare-bones generic kernel along with the source to build a better one. One of the steps in the installation process was configuring the kernel to your requirements, followed by the compilation phase. This was time consuming and potentially overwhelming for new users.
The Holy Grail of Linux Distributions is a platform-specific (ideally OS-neutral) loader (U-boot, GRUB etc.), a generic kernel (one per processor architecture) and a collection of loadable modules. Since not all hardware sits on discoverable (plug-and-play) buses like PCI and USB, what is missing from this picture is a mechanism to describe the rest of the hardware; Device Tree is that mechanism.
Device Tree (DT) is the recommended way to describe hardware on Linux platforms (although it is actually OS-independent). It is a hierarchical structure consisting of nodes, sub-nodes and properties. It is not unlike XML in some respects, but thankfully it is more readable, less verbose, and comes with a standard binary representation, Flattened Device Tree (FDT), that is easy for programmes to parse and manipulate. Desktop processor platforms made the switch to DT years ago, and after years in the wilderness the ARM SoC platforms are catching up.
So, why should Raspberry Pi use Device Tree? The change is primarily a practical one. Until now, supporting some peripheral cards has required the addition of "struct platform_device" objects to the board support code. These are usually conditionally compiled based on the kernel configuration options, but in order to prevent regular users from having to compile their own kernel these options are turned on in the standard builds. As a result, at boot time, many (typically unwanted) modules are loaded unless they added to the blacklist (which prevents the automatic loading but still allows subsequent manual loading). Insufficient blacklisting could lead to nasty contention for GPIO pins, usually experienced after a kernel update since the blacklist file (/etc/modprobe.d/raspi-blacklist.conf) isn't a part of the kernel and hence doesn't automatically get updated.
Device Tree turns this system on its head, by replacing those "struct platform_device"s with nodes in the DT, allowing users to control which devices are enabled and hence which modules get loaded. Adding a new device driver module to the kernel doesn't automatically result in a module being loaded - the appropriate nodes must also be added to the DT.
Fixing the problem
If you are really impatient and just want out, or if for some reason your bit of hardware doesn't yet have a suitable overlay, add "device_tree=" to your config.txt and reboot. But be aware that this option may not be supported indefinitely.
A better choice would be to run:
- Code: Select all
Select "Advanced Options" from the menu, then either "SPI" or "I2C", and enable the interfaces there. If you want the driver modules to load automatically (and you probably do) then answer "Yes" to the follow-up question. raspi-config can also be used to disable and re-enable Device Tree.
Writing Device Trees is hard, particularly if you've never encountered one before. It shouldn't be necessary to write (or even edit) one in order to use commercial hardware. So the Raspberry Pi loader (start.elf, and its siblings) can combine a base DT Blob (DTB) with a number of overlays, each of which can be customised with a number of parameters. This is all controlled from /boot/config.txt.
The mechanism is described in a new README file (/boot/overlays/README - you may need to update your firmware), and full documentation can be found here: http://www.raspberrypi.org/documentation/configuration/device-tree.md.
- My I2C interface has disappeared. What do I do?
Add "dtparam=i2c_arm=on" to your config.txt and reboot. If you are feeling terse you can omit the "=on", since that is the default option. Or use raspi-config, as described above.
- My SPI interface has disappeared. What do I do?
Add "dtparam=spi=on" to your config.txt and reboot. Or use raspi-config, as described above.
- My I2S interface has disappeared. What do I do?
In case you haven't spotted the pattern, add "dtparam=i2s=on" to your config.txt.
And reboot. This one isn't in raspi-config.
- My lirc-rpi module doesn't load anymore. What do I do?
- But what about the lirc-rpi module parameters?
Add them to the end of the dtoverlay line, like this: "dtoverlay=lirc-rpi,gpio_in_pin=16,gpio_in_pull=high".
- What about "w1-gpio"?
Slightly more complicated. If you require the external pullup enable pin, use:
(where <x> and <y> are GPIO pins, obviously).
If you are using the parasitic power (power over data, 2-wire) mode, add ",pullup=1" (or ",pullup=on")
- How about "pps-gpio"?
Another pesky overlay. You can probably guess the name and parameter:
- And what about my audio card?
Add one of the following:
- I2C Real Time Clock?
where <model> is one of: ds1307, ds3231, pcf2127, pcf8523, pcf8563
Note that the old individual RTC overlays have been deprecated and will be deleted in future releases.
- Can I give my Pi a heartbeat LED?
- Cool: thanks.