foxt
Posts: 4
Joined: Thu Apr 12, 2012 5:58 pm

GPIO cleanup and start-stop-daemon

Tue Dec 10, 2013 9:09 pm

I am new to UNIX and PYTHON, like soe many others brought to it by the mission of RPi. I am experimenting with running a python script as a daemon on boot using start-stop-daemon. I have used google, various other sites, etc to try and learn more about how all of this works so that I can understand my problem, but I am stuck and am hoping that someone can point the way. Being new, I may not know enough to recognize the solution when I see it, or to search for it correctly.

The script uses RPi.GPIO to manage the GPIO inputs and outputs. I have the code set up to run GPIO.cleanup at the end. When I run the script directly in python via the terminal, it runs fine and terminates in a controlled fashion, cleaning up GPIO on its way out. When I run the script as a daemon via start-stop-daemon, it starts ok but it does not gracefully exit when I execute "stop" (never gets to GPIO.cleanup). To illustrate, a simple example (I put the print statements in there to convince myself that it was working the way I thought it should via the terminal).

Code: Select all

#!usr/bin/python

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.OUT)

try:
    while True:
        GPIO.output(27,1)
        sleep(2)
        GPIO.output(27,0)
        sleep(2)

except KeyboardInterrupt:
    print "loop ending"

finally:
    print "cleaning up"
    GPIO.cleanup()
I have seen references to threads and/or daemons not handling interrupts well, and I suspect that is what I am experiencing here. If start-stop-daemon just kills this little script without letting it exit via "finally:", is there something in RPi.GPIO (or alternatives) that will allow me to clean things up after the daemon is killed? I did try putting GPIO.cleanup() in it's own little script and starting/stopping that as a daemon right after I stop the main script, but it has no effect. I know that it is good practice to cleanup after yourself, so if a daemon does allow you to cleanup from within the script, how do you accomplish it?

User avatar
joan
Posts: 12780
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO cleanup and start-stop-daemon

Tue Dec 10, 2013 9:19 pm

I don't know if this will work but it's worth a try.

import atexit
...
atexit.register(GPIO.Cleanup)

foxt
Posts: 4
Joined: Thu Apr 12, 2012 5:58 pm

Re: GPIO cleanup and start-stop-daemon

Tue Dec 10, 2013 10:27 pm

Thank you for the reply.

I tried your suggestion, and it did not work. Looking into atexit, I found "The functions registered via this module are not called when the program is killed by a signal not handled by Python". My guess is that using start-stop-daemon to start and stop the script falls under the category of "signal not handled by Python"?

User avatar
joan
Posts: 12780
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO cleanup and start-stop-daemon

Tue Dec 10, 2013 10:37 pm

Do you handle any signals in the script?

Something like

Code: Select all

import signal
def handleSIGTERM():
    GPIO.cleanup()
signal.signal(signal.SIGTERM, handleSIGTERM)

foxt
Posts: 4
Joined: Thu Apr 12, 2012 5:58 pm

Re: GPIO cleanup and start-stop-daemon

Wed Dec 11, 2013 1:44 am

Thank you again.

start-stop-daemon allows me to specify the signal to be used when stopping, and I had tried that before with no success. Based upon your suggestion, I looked at it again and got it to work this time. The first time I tried it, my understanding was that start-stop-daemon by default issues the TERM signal when stopping, so I had my script set up to exit gracefully on that signal but I did not specify --signal TERM . This time, I specified -- signal TERM in the call to start-stop-daemon, and it worked! Maybe the default behavior is the same as sending a TERM signal, but apparently start-stop-daemon doesn't actually send TERM? So much to learn ...

Anyway, thank you again!

Return to “Python”

Who is online

Users browsing this forum: No registered users and 13 guests