Re: [dev] Sane GPIO library (esp. for Raspi)

From: Kurt Van Dijck <dev.kurt_AT_vandijck-laurijssen.be>
Date: Tue, 31 Oct 2017 08:46:32 +0100

> which do you consider the GPIO libary for C that least sucks? I need it
> especially for a Raspberry Pi project. Wiring Pi (http://wiringpi.com/)

such library intersects vertically in a layered model, and therefore
is wrong at each level that it intersects. An incomplete list of
inherent problems:
* userspace applications need alternate resource sharing primitives
* assuming that applications need a library with SoC specific
  code/drivers is wrong.
* You mix hardware description with userspace application code.

> looks easy and sane, but I wasn't able to try it out yet (still waiting
> for a hardware shipment, but I don't want to sit around idle in the
> meantime...).

The truth is that such GPIO library makes you mimic bare-metal programs
like on arduino, but in fact you bypass all advantages of a proper OS.

I deal with GPIO for my projects by creating a device-tree overlay that
describes the hardware (input/output, active-low, ...).
Inputs are grouped in an input device (using gpio-keys driver), outputs
become leds (leds-gpio drivers).
This device-tree overlay is loaded in runtime (not using proprietary
bootloader support) in configfs.
I can thus load and unload devices, and gpio's are properly propagated
to userspace via device drivers.

As an illustration, I include my latest pump controller (using Raspberry
Pi 0 wireless) device tree. I has 4 outputs and 2 inputs ... (including 1
real led, and 1 shutdown button)

        /dts-v1/;
        /plugin/;

        / {
                compatible = "brcm,bcm2708";

                fragment_AT_0 {
                        target-path = "/";
                        __overlay__ {
                                swimsparelays: swimspa_AT_0 {
                                        compatible = "gpio-leds";
                                        pinctrl-names = "default";
                                        pinctrl-0 = <&swimsparelays_pins>;

                                        relay_AT_5 {
                                                label = "zwemled";
                                                gpios = <&gpio 5 0>;
                                                linux,default-state = "off";
                                        };
                                        relay_AT_6 {
                                                label = "pump";
                                                gpios = <&gpio 6 0>;
                                                linux,default-state = "off";
                                        };
                                        reed_AT_24 {
                                                label = "option";
                                                gpios = <&gpio 24 0>;
                                                linux,default-state = "off";
                                        };
                                        led_AT_23 {
                                                label = "techled";
                                                gpios = <&gpio 23 0>;
                                                linux,default-trigger = "heartbeat";
                                        };
                                };
                                swimspainputs: swimspa_AT_1 {
                                        compatible = "gpio-keys";
                                        #address-cells = <0>;
                                        #size-cells = <0>;
                                        pinctrl-names = "default";
                                        pinctrl-0 = <&swimspainputs_pins>;

                                        /* all gpio's are now active low */
                                        sysrq_AT_12 {
                                                gpios = <&gpio 12 1>;
                                                linux,code = <99>;
                                                wakeup-source;
                                        };
                                        key_AT_17 {
                                                gpios = <&gpio 17 1>;
                                                linux,code = <16>; /* "Q" */
                                                wakeup-source;
                                        };
                                };
                        };
                };
                

                fragment_AT_1 {
                        target = <&gpio>;
                        __overlay__ {
                                swimsparelays_pins: swimsparelays_pins_AT_0 {
                                        brcm,pins = <5 6 24 23>;
                                        /* 0=in, 1=out */
                                        brcm,function = <1 1 1 1>;
                                        /* 0=none, 1=low, 2=high */
                                        brcm,pull = <1 1 1 1>;
                                };
                                swimspainputs_pins: swimspainputs_pins_AT_1 {
                                        brcm,pins = <12 17>;
                                        /* 0=in, 1=out */
                                        brcm,function = <0 0>;
                                        /* 0=none, 1=low, 2=high */
                                        brcm,pull = <2 2>;
                                };
                        };
                };
        };

Having such device tree loaded in the system, I can access my GPIO's
using existing API's, using existing tools, ...

I challenge you propose scenarios where a GPIO library performs better.

Kurt
Received on Tue Oct 31 2017 - 08:46:32 CET

This archive was generated by hypermail 2.3.0 : Tue Oct 31 2017 - 08:48:15 CET