Using GPIO interrupts to turn on an LED when a button is pressed

What is the best way to turn on an LED when a button is pressed? Is the best place for this in user space, or the kernel? My logic is very simple, and you can see the bash script I have below. However, this eats the CPU because I do not have the sleep time implemented (can’t do less than 1 second in bash). Any suggestions? I would prefer to do this in the kernel, but I haven’t found really good examples. The one I found is: http://mondi.web.cs.unibo.it/gpio_control.html, but I’m a little confused where everything goes. My bash script is below:

#!/bin/bash

If you only need to turn the LED on or off based on a GPIO, you can
use a LED trigger to do it. You'll have to configure GPIO 45 with the
gpio-leds driver so that it gets exposed in the /sys/class/leds
directory. Here's what to do if you want the usr0 LED to follow the
state of GPIO 44 :

# echo gpio > /sys/class/leds/beaglebone\:green\:usr0/trigger
# echo 44 > /sys/class/leds/beaglebone\:green\:usr0/gpio

One note: I forgot whether gpio triggers were compiled into the
Angstrom and Ubuntu kernels. You can check by running "cat
/sys/class/leds/beaglebone\:green\:usr0/trigger" to see what triggers
were compiled into the kernel.

If you want to do more with GPIO 44 than just turn on and off an LED
(and since it is a button), you could configure it with the gpio_keys
driver. That way you can have your app respond to key presses which
could be convenient.

Another way to avoid polling a GPIO is to call poll(2) or select(2)
from your application on the /sys/class/gpio/gpioNNN/value file.
That's probably too much work given what you want to accomplish, but
it's documented in the Linux kernel under Documentation/gpio.txt.

Frank

Actually, you can sleep for less than 1s in bash:

time sleep 0.5

real 0m0.503s
user 0m0.001s
sys 0m0.001s

Frank,

Is there a way to do this in the device tree? My original question was very generic, but let me explain a little more. What I am actually doing is monitoring an ignition signal in a vehicle and when I see the ignition go high, I want to turn on the backlight_enable pin on my LCD. When the ignition goes low, I want to turn off the backlight. I can do this just fine in my application by monitoring the GPIO value, but the problem I have is that it takes somewhere around 10-15 seconds to boot up so it looks like there is nothing going on while the BBB is booting. Ideally this would happen in the kernel rather than user space, but I’m not sure where to start. I should note that the BBB is turned on before the ignition is turned on, but there is no guarantee that the BBB will be finished booting by the time the user turns on the ignition. Any suggestions? Thanks!

Hi Brent,

Frank,

Is there a way to do this in the device tree?

Short answer, I don't think so.

I think that the led gpio trigger strategy is the best one for you,
since it's all handled by the kernel. In your dt description that
creates the led, you can set a trigger (the heartbeat on the usr0 LED
on the beaglebone is an example.) However if you set the led trigger
to "gpio", I don't see how you actually set the gpio in the dt file.
Looking at ledtrig-gpio.c in the kernel, I don't see any dt bindings.
That doesn't mean that there's not a way to do it completely with dt.
I just don't know how.

If you're desperate and you can't find the right way of doing it using
device tree, I'd be tempted to copy/paste ledtrig-gpio.c to
ledtrig-mygpio.c and modify it to make your gpio the default one. That
way, you'd just specify "mygpio" as the LED trigger in the dt file and
it would know which gpio to monitor. Definitely a hack, though, so
hopefully someone here knows a better way if it is actually possible
to do in a dt file.

My original question was very generic, but let me explain a little more. What I am actually doing is monitoring an ignition signal in a vehicle and when I see the ignition go high, I want to turn on the backlight_enable pin on my LCD. When the ignition goes low, I want to turn off the backlight. I can do this just fine in my application by monitoring the GPIO value, but the problem I have is that it takes somewhere around 10-15 seconds to boot up so it looks like there is nothing going on while the BBB is booting.

Ugh. I assume that you've already tried to reduce the boot time. If
you configure the backlight_enable pin to be a gpio-led, and set the
/sys/class/led/.../trigger to gpio and then set the gpio as the very
first thing that you do at init time (before starting your app or
anything else), is that fast enough?

Ideally this would happen in the kernel rather than user space, but I'm not sure where to start. I should note that the BBB is turned on before the ignition is turned on, but there is no guarantee that the BBB will be finished booting by the time the user turns on the ignition. Any suggestions? Thanks!

It might be easier to connect the ignition signal directly to the
backlight_enable pin using a physical wire. :slight_smile:

Frank

I figured that was the case, but thought I’d check. At this point I will just connect the two together with a wire - next boards will just have this mod on there. Thanks so much for your help!