Startup-/Shutdown Button for the Raspberry Pi 4

From: Dr. Rolf Jansen <freebsd-rj_at_cyclaero.com>
Date: Wed, 13 Jul 2022 01:17:00 UTC
One week ago I started with exploring the Raspberry Pi 4 B, which might be a substitute for the aging BeagleBone Blacks for my future projects.

I very much like the built-in power button facility of the BBB, and unfortunately the RPi 4 has nothing comparable - the one button to rule it all.

I read a lot of howtos and blog posts (mostly for Linux) and nothing was really worth to give it even a try, compared to live without the button. Well, this is not becoming an elaborated question, but here I am going to elaborate my solution for FreeBSD.

1. I Prepared a momentary push button for connecting it to the RPi:
            ___ 
             | /
             |/
             /
            /
         +-o      o--------+
         |        |        |
         |       [R] 100 Ω |
         |        |        |
         o        o        o
       Pin 5    Pin 6    Pin 13
      (SCL 1)   (GND)   (GPIO 27)

2. I created a shutdown daemon in C for FreeBSD, lurking for push button
   events on a GPIO port: https://github.com/cyclaero/shutdd

   clang -g0 -O3 -fsigned-char -Wno-empty-body -Wno-parentheses shutdd.c -lgpio -s -o /usr/local/bin/shutdd

   shutdd [-p file] [-f] [-n] [-b] [-g] [-h]  
    -p file    the path to the pid file [default: /var/run/shutdd.pid]  
    -f         foreground mode, don't fork off as a daemon.  
    -n         no console, don't fork off as a daemon.  
    -b         GPIO bank id [default: 0].  
    -g         GPIO line id [default: 27].  
    -h         shows these usage instructions.  

   echo "/usr/local/bin/shutdd" >> /etc/rc.local 

Restart and ready for testing the RPi's Power Button.

shutdd does not poll the state of the GPIO port, but instead utilizes FreeBSD's user space interface for GPIO interrupts for lurking on state changes of the GPIO line - default GPIO.0.27. Therefore, no significant load is imposed on the CPU's.

After 2 hs of operation, in output of ps -ax:
...
550  -  Is     0:00.03 /usr/local/bin/shutdd
...

- No CPU load !!!

- Pressing the power button does the same as shutdown -p now

- Pressing the power button when the RPi is down but still connected to the 5 V power supply lets it starting up.

BTW, I left the RTC DS3231 on I2C 1. That means, the RTC and the power button share the same pins for SCL 1 and GND.