Raspberry Pi GPIO states at boot time

When external hardware is connected to the Raspberry Pi, it can be important to know the initial state of the GPIO pins at boot time. For example, if we have a motor connected to a GPIO pin, it could be a problem if the motor starts running as the system boots up. Ideally, we would want all the pins defined as inputs at start up, but that doesn’t seem to be the case with some of the Pi GPIO pins.

Fortunately, there’s now a solution in the form of the device tree pin configuration. This involves creating a pin configuration source file, and compiling that to a binary “blob” which is loaded by the OS at start up. This source file can configure pins as inputs, outputs or in special function modes (UART serial port for example). It can also configure whether a pin has pull-up or pull-down enabled.

This proved very useful for my Espiresso project, when I needed a pin to enable the pump at start up. Having run out of general GPIO pins, I was forced to use GPIO15 (RXD) which is configured as a pull-up UART pin by default. This would have resulted in the pump running as the system booted. However, by editing the device tree configuration, it was possible to set this pin as an input with pull-down mode, which prevents the external hardware being switched on during boot. The GPIO pin can then be reconfigured as an output by the application, after the Pi has booted.

As an update to this, there have been a couple of important developments with device-tree since I wrote this, which I’ll summarise briefly here:

  • You can now create device tree overlays, to configure specific GPIO pins at boot. However, with NOOBS these do not take effect immediately (in which case the dt-blob.bin will still be needed).
  • With NOOBS, the dt-blob.bin file needs to be placed on the recovery partition. Even then, I found the only way to ensure the pins stay in the desired state through the entire boot process is to have the dt-blob.bin on both recovery and /boot partitions.
  • In conclusion: avoid NOOBS for this application, and go with a vanilla Raspbian install

12 thoughts on “Raspberry Pi GPIO states at boot time”

  1. I’m having a problem where, when you power up the raspberry, one or both of my motors run uncontrollably. until you get into terminal and do the “stop” command.
    this is using python.

    1. Hi tj

      It sounds like the device tree configuration might help! Of course it depends if your motors are enabled by active high or active low, and you would need the appropriate initial settings.

      I wrote some more detailed instructions here, which describe how to compile the source file:
      Scroll down to the part titled:
      “GPIO initialisation at boot time”

      Here’s a direct link to my own device tree source file, as an example:

      Hope this helps

  2. Hi James,

    First, thank you for your port. I am also having the same problem, I have a motor connected to the RPi and it starts moving when the RPi is powered up.

    Now, I am writing to you because the link for the .dtc file is not working (https://code.google.com/p/espiresso/source/browse/trunk/gaggia/dt-blob/dt-blob.dts) Do you have another place from where to download the file? Or another suggestion? In my case, to be sure not to mess up with my RPi, I would like to just change the initial state of a couple of GPIO (19 and 26). Maybe I can get the ‘original’ .dts file and you can suggest me which lines to change. Thank you in advance! Lorenzo.

    1. I’ve not yet tried this on the Pi 3 yet, but as device tree is a fairly recent introduction to the OS, I assume it probably would work there.

  3. Hi James, thank you for all you share with us.
    I have developed a hardware board that uses RPI as main processor. Unfortunately the only two output of my board, that controls 2 power mosfet, are connected to gpio2 and gpio3.
    As you know these pins are used as wake from halt. A shortcut between gpio2 and gpio3 will powerup the raspberry from shutdown.
    So I’ve modified the dt-blob.dts, adding 2 line for pin@p2 and pin@p3 and setting them as output-pulldown, the problem was mitigated but not totally solved.
    Infact at shutdown the two pin are pulled up anyway. Only after 1 second after power reset the two pins are pulled down as I wish.
    The problem is the same if I issue a simple reboot. (2 seconds of pulled up state)
    I need that at reboot the two pins stay low for all the time (shutting down + starting up).
    So have you any suggest for me?
    Thank you in advance for your kindly reply

    1. Hi Nicolò
      Sorry it’s taken a while to reply. Are you using a direct install of Raspbian, or using Noobs? The reason for asking, is that I saw an issue like the one you’re describing with Noobs (see article above). If you are using Noobs, reinstalling with Raspbian may resolve the issue.
      Otherwise, if you are using Raspbian and Device Tree isn’t helping, then the only other option I can think of would be to use some extra hardware (for example, if you’ve run out of GPIOs, perhaps use a latching shift register such as 74HC595 to add some more GPIOs)
      Best regards

      1. Hi James,
        thank you for your replay.
        I’m using Raspbian. I was wondering in some trick to prevent RPi wake from halt function, but it seem it can not be disabled.
        The problem is that my board was produced in hundreds of pieces before the new function (wake from halt) were developed. The board is internally connected and i have not chance to modify the electric path for adding other external hardware. This happens when the producer of a board like Raspberry is more interested to it use as a pc board then an embedded system. In my opinion the rpi is used in many context, when is done a deep modify of gpio behavior they should provide a transparent way to disable or enable their functions. These games could cost many dollars to other companies that use raspberry as a part of greater project.

        1. Hi Nicolò
          It appears that wake from halt is configured inside the bootcode.bin firmware which runs on the GPU:
          Unfortunately, the trail ends there because the source code and tools to modify bootcode.bin aren’t available:
          Not sure if you could roll back to use an old firmware version with a recent OS release.
          Otherwise it looks like there’s no option but to redesign the PCB or use an intermediate PCB/cable/connectors to swap the pin order.
          I can understand your frustration!

Leave a Reply

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