I am working on an automatic shutdown based on an external signal (through a digital IO line), on a BB black, running Debian Jessie.
I build a program that monitors the digital line and when that line goes high, the program calls
system("/sbin/shutdown -h now");
When I run that program interactively, it takes anywhere between 6 to 10 seconds to shutdown following the digital line flip. I use an LED to tell me when the process detects the bit flip so I can reliably count the time to shutdown. The actual shutdown is evident because all the lights go off. At that point I have to recycle power to start again, which is exactly what I want.
However, when I put the same program to run as a service (by adding a service in /lib/systemd/ and using systemctl to start it), the system takes over 30 seconds to shutdown, sometimes a minute or two. I know the program is running as a service because I can see the LED I am using as feedback. The LED changes blink rate when the ‘service’ detects the GPIO change so I can tell the program is getting to the point of making the system call, it just takes so much longer. In fact, initially I thought it did not work, only to have the system shutdown on my suddenly a couple of minutes later.
So the situation is that a program running directly goes through a shutdown almost instantaneously but when run through a service, it takes significantly longer. Any idea why?
By the way, I have also tried
sync();
reboot(LINUX_REBOOT_CMD_POWER_OFF);
instad of system("/sbin/shutdown -h now’), and I get more or less the same behavior.
My guess is your systemd service isn’t exiting and so the shutdown pauses until your service exits or after a timeout, the service is sent a kill signal to exit.
That was it - after issuing the shutdown command I had put the program on an endless loop with a usleep; instead, the service now exits right after issuing the reboot command the reboot indeed occurs as before, within 8 seconds or so.
Temporarily pressing the power button (or pulling the PWR_BUT line to ground) does shutdown the system but it seems to take much longer, often more than a minute. I have put together a small PIC and a super-capacitor setup; the PIC monitors the main power line and triggers the shutdown and the capacitors can power the BBB for about 15 to 20 seconds so shutting down fast is rather important. Once the system is down (as evident by the VDD_5V going to 0V), the PIC turns off the main regulator and it then waits for main power to come up and the capacitors to charge before it enables the regulator again which will boot the BBB next time power arrives.
Using the service to shutdown or issuing a shutdown -h now’ takes 8 seconds to power down most of the time. Sometimes it takes long, but rarely does it seem to take more than 15 seconds. Pressing the power button consistently takes over 45 seconds to over a minute. I have not experimented enough to feel extremely confident on all of this, but the shutdown command appears to consistently be faster than the power button. Maybe there is a way to make that shutdown faster, but I have not found anything obvious.
Regarding talking to the power management chip, I am resisting the urge for a couple of reasons - it will take time away from working on the design of my system and even if I were to invest the time, it would make my design more BBB specific; right now, the setup I’m using can work with just about any linux system with a single input pin and an exposed power rail which can be used as feedback for when the shutdown is done.
If there is a straightforward way to do the same without using a service process, I would welcome the instructions, but I just don’t know enough about it right now.