I am developing a power supply with a supercapacitor to give around 30 seconds of reserve power so the pi can safely shut itself down on power loss.

I have a working gpio-poweroff definition in /boot/config.txt:

# Ensure no pullups/pulldowns on input for gpio17 before defining it as
# the poweroff pin. 

This successfully removes the power to my pi on shutdown. I had assumed that configuring the pin as input would mean that I could read from it but I haven't been able to figure out how. It looks like I could poll it through sysfs but I don't want to poll and it seems that sysfs is being deprecated.

Looking in /proc/bus/input/devices, I don't see that gpio defined, though 2 others that I have defined are there.

gpioinfo shows me this:

. . .
line  15:       "RXD0"       unused   input  active-high 
line  16:     "GPIO16" "KEY_POWER2"   input   active-low [used]
line  17:     "GPIO17" "power_ctrl"   input   active-low [used]
line  18:     "GPIO18"       unused   input  active-high 
line  19:     "GPIO19"       unused   input  active-high 
. . .

And gpioget 0 17 tells me Device or resource busy.

I guess I should explain that the pin can be driven low temporarily by a button to tell the pi to shut itself down. This is separate from the actual power-sensing input, which works fine:


I could connect another gpio to the button, but that seems like a cop-out, and I would like not to "waste" a gpio, which I may have other uses for.


Final (I hope) followup:

After looking through a lot of code, hacking on pigpio and others, I have decided that this is a lost cause.

Yes, I can directly access the gpio pins using low-level access through /dev/gpiomem (and others), but that sort of code will not be future-proof, and most of the code examples I've looked at are deficient in some way or other. One notable problem is with a lack of memory barriers, and yes I could figure them out for my purposes but it's all a terrible hack and not "the right way" to do things.

So, I'm going to use chardev GPIO through libgpiod which is "the right way" and should continue to work well into the future. Of course, this leaves me with my original problem with gpio-poweroff marking that gpio as busy.

So, to hell with gpio-poweroff. I'll manually switch-off the power as the last stage of shutdown with a little systemd hack. Initial testing shows that this seems to work: shutdown powers off the pi, and the gpio is able to detect use of the button.

Thanks folks, for the responses.

2 Answers 2


gpio-poweroff provides a pin to send a signal to external circuitry.

The documentation is unclear, but I read input as putting the pin in a high impedance state (aka tri-state) NOT that it is used as input.

Name:   gpio-poweroff

Info:   Drives a GPIO high or low on poweroff (including halt). Using this
        overlay interferes with the normal power-down sequence, preventing the
        kernel from resetting the SoC (a necessary step in a normal power-off
        or reboot). This also disables the ability to trigger a boot by driving
        GPIO3 low.

        The GPIO starts in an inactive state. At poweroff time it is driven
        active for 100ms, then inactive for 100ms, then active again. It is
        safe to remove the power at any point after the initial activation of
        the GPIO.

        Users of this overlay are required to provide an external mechanism to
        switch off the power supply when signalled - failure to do so results
        in a kernel BUG, increased power consumption and undefined behaviour.

Usage:  dtoverlay=gpio-poweroff,<param>=<val>

Params: gpiopin                 GPIO for signalling (default 26)

        active_low              Set if the power control device requires a
                                high->low transition to trigger a power-down.
                                Note that this will require the support of a
                                custom dt-blob.bin to prevent a power-down
                                during the boot process, and that a reboot
                                will also cause the pin to go low.
        input                   Set if the gpio pin should be configured as
                                an input.
        export                  Set to export the configured pin to sysfs
        active_delay_ms         Initial GPIO active period (default 100)
        inactive_delay_ms       Subsequent GPIO inactive period (default 100)
        timeout_ms              Specify (in ms) how long the kernel waits for
                                power-down before issuing a WARN (default 3000).
  • I think you may be right about input being for putting the pin in a high impedence state. Unfortunately gpio_poweroff does not let you set the pullup/pulldown state which is a little unhelpful.
    – Marc
    Apr 7, 2023 at 17:02
  • It is simple to add an external pullup (after all you already have external circuitry attached).
    – Milliways
    Apr 7, 2023 at 22:15
  • Not easy to remove the internal one though.
    – Marc
    Apr 8, 2023 at 18:16

pigpio will let you read the level of a GPIO.

E.g. if the pigpio daemon is running

pigs r 17

will return the current level of GPIO 17.

If you don't want the overhead of the pigpio daemon you could easily modify tiny GPIO to do what you want.

  • Thanks. I hadn't tried pigpio, I'll look into it. Wow, pigpiod takes a lot of cpu time on an old pi :-)
    – Marc
    Apr 7, 2023 at 17:03
  • It is doing a lot in the background (e.g. sampling GPIO 0-31 @ 200 thousand times per second).
    – joan
    Apr 7, 2023 at 19:19

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .