GPIO in /sys/class/leds/

Hello, I am doing a project with Raspberry Pi and OpenWrt. I need to attach indicators LED.
I have found guides on how to control GPIOs with scripts. Is there any way it can be attached with triggers?

Standard Linux methods work β€” you may need to export additional GPIOs that aren’t defined in the DTS

Is there any other way other than having to re-compile the build with modified DTS?

If you want to manipulate the GPIO directly, export-ing it should be sufficient.

If you want to have the kernel recognize that GPIO as a gpio-led, then, as far as I know, you need to change the device tree as known by the running kernel.

It may be possible to modify the kernel's notion of its device tree on the fly, but I have not looked into this in any depth.

The DTS of ramips devices is located directly on the DTS folder with .dts extension. I've searched and couldn't find how this can be done for the brcm2708 SoC.

According to OpenWrt documentation board.d should contain scripts for defining device-specific default hardware, like LEDs and network interfaces.

I am unable to locate
target/linux/brcm2708/base-files/etc/board.d/01_leds

diag.sh only has the LED configuration.

Any help will be appreciated.
Thanks.

Is there /sys/class/gpio directory?

echo <num> > /sys/class/gpio/export                  # export GPIO pin
  (ex.: echo 29 > /sys/class/gpio/export)
echo "out" > /sys/class/gpio/gpio<num>/direction     # set direction to "out"
echo "1" > /sys/class/gpio/gpio<num>/value           # set GPIO pin to HIGH
echo "0" > /sys/class/gpio/gpio<num>/value           # set GPIO pin to LOW
echo <num> > /sys/class/gpio/unexport                 # unexport GPIO pin

referenced: http://hacklabos.org/2014/04/playing-with-gpio-and-sensors-on-openwrt/

I have already been through this.

What I actually want is to attach the GPIO with triggers.

For that i need GPIOs in /sys/class/leds/.

I see. When using LED trigger, it certainly needs to be defined as LED.

The core part of DTS files for Raspberry Pi devices exists here:

1 Like

The otherway would be to hotplug trigger, handler scripts that manipulate the GPIO's directly... ( assuming they are unassigned )....

One must be prepared to customise, if one wished to customise :slight_smile:

1 Like

Hello, I was able to associate the network status to the GPIO LEDs with a shell-script.
But I couldn't find anything on how to associate netdev trigger(or any other triggers) with GPIOs.

The only way is to compile a kernel with the GPIOs as LEDs.
Can somebody please guide me in the right direction.
Thanks.

I am completely clueless on how to proceed with this patch.

Any help would be much appreciated.
Thanks.

root@OpenWrt:~# cat /etc/hotplug.d/iface/00-netstate 
[ ifup = "$ACTION" ] && {

    #############################
    /your/script/here dosomething

	uci_toggle_state network "$INTERFACE" up 1
	[ -n "$DEVICE" ] && {
		uci_toggle_state network "$INTERFACE" device "$(uci -q get network.$INTERFACE.ifname)"
		uci_toggle_state network "$INTERFACE" ifname "$DEVICE"
           
	}
}


[ ifdown = "$ACTION" ] && {
            
           ##############################
           /your/script/here dosomethingelse
}

etc. etc. etc.

As a side note: the web ui > collectd plugin > exec offers another window into triggering multitudes of events.... it can be bi-directional too so that one could extensify the feeedback.

1 Like

If you want to write a trigger off something that generates a UCI event, the above approach (with the proper script and tests) is an easy, no-compile option.

If you want to expose the GPIOs as gpio-led elements and have the "standard" Linux triggers able to directly attach to them, you'll need to build your own image.You'd need to patch the DTS file to add the instances of gpio-led. Since I don't see a DTS in the OpenWrt source, I'm assuming it just uses the upstream version.

Basically, you want to overlay the definitions you need. DTS lets you keep everything but easily add/change anything you define in the "new" file compared to what that file gets from its #include statements.

1 Like

UPDATE: I modified the DTS for brcm2710 Raspberry Pi 3B and added a section for the new LEDs:

+&leds {
+	act_led: act {
+		label = "led0";
+		linux,default-trigger = "mmc0";
+		gpios = <&virtgpio 0 0>;
+	};
+
+	pwr_led: pwr {
+		label = "led1";
+		linux,default-trigger = "input";
+		gpios = <&expgpio 7 0>;
+	};
+
+	mng_led: mng {
+		label = "led2";
+		linux,default-trigger = "input";
+		gpios = <&expgpio 21 0>;
+	};
+};

and

+/ {
+	__overrides__ {
+		act_led_gpio = <&act_led>,"gpios:4";
+		act_led_activelow = <&act_led>,"gpios:8";
+		act_led_trigger = <&act_led>,"linux,default-trigger";
+
+		pwr_led_gpio = <&pwr_led>,"gpios:4";
+		pwr_led_activelow = <&pwr_led>,"gpios:8";
+		pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
+
+		mng_led_gpio = <&mng_led>,"gpios:4";
+		mng_led_activelow = <&mng_led>,"gpios:8";
+		mng_led_trigger = <&mng_led>,"linux,default-trigger";
+	};
+};

Upon compiling, it fails to compile the kernel.

recipe for target 'target/linux/install' failed
make[2]: **** [target/linux/install] Error 2

Any clue where this might have gone wrong?

I'm not familiar with the __overrides__ syntax. At least in my experience, adding or overriding would be accomplished with the &leds section. Nodes or properties can be deleted with the DTS /delete-node/ or /delete-property/ syntax, such as described in https://elinux.org/Device_Tree_Source_Undocumented#Deleting_nodes_and_properties

Running make V=s target/linux should reveal where you've got problems. I'm guessing its in the building of the DTB from the DTS. If so, it has always given me a line for the problem it had (and I've had quite a few).

The error you posted is a generic one.... around 10 to 20 lines up .... the last of the "dts/dtb" ones is the one where it really fails......

But that will probably just say / error parsing... etc... etc...

I think there are some online tools that will "attempt" to validate a dts somewhat.....

But seeing as you've been a good sport..... .put the dts ( and included dtsi ) on pastebin....... you got them from the buildroot /target/linux/b.... folder right?

Then all the peeps who might help you to overcome this minor setback will to tooled for the purpose :slight_smile:

For a start tho'

		act_led_gpio = <&act_led>,"gpios:4";
		act_led_activelow = <&act_led>,"gpios:8";;

		mng_led_gpio = <&mng_led>,"gpios:4"; < CONFLICTS with ^?
		mng_led_activelow = <&mng_led>,"gpios:8"; < CONFLICTS with ^?

So, for a quick edit something like this? would be what I would have tried....

#include "bcm2708.dtsi" < MAY HAVE SOME FUNDAMENTAL GPIO PIN DEFINITIONS > EDIT CHECKED IT OUT ITS GENERIC NOTHING THERE in the raw sources anyway

&leds {
	act_led: act {
		label = "led0";
		linux,default-trigger = "mmc0";
		gpios = <&gpio 47 0>;
	};


	customled: ledtest {
		label = "custled0";
		linux,default-trigger = "br-lanorsomething";
		gpios = <&gpio 21 0>;
	};
};

/ {
	__overrides__ { < LIKE JEFF SAID DUNNO ABOUT THIS SECTION

		act_led_gpio = <&act_led>,"gpios:4";
		act_led_activelow = <&act_led>,"gpios:8";
		act_led_trigger = <&act_led>,"linux,default-trigger";

		customled_gpio = <&customled>,"gpios:21etc";
		customled_activelow = <&customled>,"gpios:22notsureaboutthisone";
		customled_trigger = <&customled>,"linux,default-trigger"; < POSSIBLYJUSTLEAVEITBLANKFORNOW

EDIT ^ lol.... search around a bit.... that's what so damn marvellous about the Pi's.... documentation / support is abundant....!!

This one half way down has a pretty decent example....
https://www.raspberrypi.org/forums/viewtopic.php?t=176449

You just have to be a bit careful with structure, version ( some formats are totally different... same device but written in a newer / older syntax ), overlaps ( search for that pin everywhere... )

You can do that in /etc/config/system

You'll need to install the right kmod-ledtrig package
https://openwrt.org/docs/guide-user/base-system/led_configuration

1 Like

Original for bcm2710:

+&leds {
+	act_led: act {
+		label = "led0";
+		linux,default-trigger = "mmc0";
+		gpios = <&virtgpio 0 0>;
+	};
+
+	pwr_led: pwr {
+		label = "led1";
+		linux,default-trigger = "input";
+		gpios = <&expgpio 7 0>;
+	};
+};

+/ {
+	__overrides__ {
+		act_led_gpio = <&act_led>,"gpios:4";
+		act_led_activelow = <&act_led>,"gpios:8";
+		act_led_trigger = <&act_led>,"linux,default-trigger";
+
+		pwr_led_gpio = <&pwr_led>,"gpios:4";
+		pwr_led_activelow = <&pwr_led>,"gpios:8";
+		pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
+	};
+};

Look at the __overrides__ section. It has the same gpios for both act_led and pwr_led by default.

Original patch: https://github.com/openwrt/openwrt/blob/master/target/linux/brcm2708/patches-4.14/950-0054-BCM2708-Add-core-Device-Tree-support.patch
Look at line number: 1583 for bcm2710

RaspberryPi DTS:https://github.com/raspberrypi/linux/blob/rpi-4.19.y/arch/arm/boot/dts/bcm2710-rpi-3-b.dts

That's okay. But how do you specify a GPIO in /etc/config/system?

The GPIO must be present in /sys/class/leds with a label. And for, that the kernel should recognize the gpio as a led.

1 Like

I did:

make target/linux/clean
make target/linux/compile V=s

The compilation completes without any errors. V=s here: https://pastebin.com/9bhzkcZt

but, during

make -j5 V=s

I get the following error:

I tried with make -j1 V=s, the same error shows up.