How to interface with the GPIO through the gpiod library?

#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>

#define CONSUMER "ExampleConsumer"
#define GPIO_PIN 25 // GPIO Pin 25

int main(void)
{
    struct gpiod_chip *chip;
    struct gpiod_line *line;
    int ret;

    // Open the GPIO chip
    chip = gpiod_chip_open_by_number(0); // Use the correct chip number for your platform, usually 0 or 1
    if (!chip) {
        perror("Open chip failed");
        return 1;
    }

    // Get the line corresponding to the GPIO pin
    line = gpiod_chip_get_line(chip, GPIO_PIN);
    if (!line) {
        perror("Get line failed");
        gpiod_chip_close(chip);
        return 1;
    }

    // Request the line as an output and set its initial value to 0 (LOW)
    ret = gpiod_line_request_output(line, CONSUMER, 0);
    if (ret < 0) {
        perror("Request line as output failed");
        gpiod_chip_close(chip);
        return 1;
    }

    // Set the GPIO line to 1 (HIGH) to turn on the LED
    ret = gpiod_line_set_value(line, 1);
    if (ret < 0) {
        perror("Set line value failed");
        gpiod_chip_close(chip);
        return 1;
    }

    // Wait for 5 seconds
    sleep(5);

    // Set the GPIO line to 0 (LOW) to turn off the LED
    ret = gpiod_line_set_value(line, 0);
    if (ret < 0) {
        perror("Set line value failed");
        gpiod_chip_close(chip);
        return 1;
    }

    // Release resources
    gpiod_chip_close(chip);
    return 0;
}

I want to run this code but gcc isn’t installed or any type of package manager.
Questions:

  1. In order for me to interface with the GPIOs I should use the sysfs virutal file system?
  2. Is it possible to use the libgpiod to interface with the GPIOs?
  3. Do I have to build the Linux from the beginning with buildroot to have GCC and other important programs installed?
  4. How can I install a package manager and gcc?
    Thanks
1 Like

Hi Mahmoud,
I got gpiod working from command line and in Python. I am using the Duo S, running the Debian image of Fishwaldo, but I think it should be same (more or less) on the official images.

I am copying my notes below (copied from here). I hope they are helpful

If GPIO 25 is giving trouble, you might wonna disable the ‘blink’ script that is running is the background (if you havnt done so already), and use duo-pinmux to switch the PIN to GPIO mode.

Working with GPIOs

The OS exposes 5 seperate ‘GPIO chips’, i.e.

debian@duos:~$ sudo gpiodetect 
gpiochip0 [3020000.gpio] (32 lines)
gpiochip1 [3021000.gpio] (32 lines)
gpiochip2 [3022000.gpio] (32 lines)
gpiochip3 [3023000.gpio] (32 lines)
gpiochip4 [5021000.gpio] (32 lines)

each of these control a group of GPIOs.
Refere also to the Duo S documentation and pinout (Duo S | Milk-V).

Care should taken when working with GPIOs as many be used for system critical functions and manipulating the wrong GPIO may screw up your system. see also GPIO permissions for libgpiod sudo or not | UDOO Forum - Also note that some PINs are running at 3.3V logic level and others at 1.8V - be careful

In the following I will give user read/write access to to gpio0. I will be working with 4 GPIOs on XGPIOA exposed on J3 running at 3.3V logic level. I have selected A18, A19, A20, A28 as these are already by default set to GPIO state in pinmux and do not appear to be used by anything else.

GPIO pin mapping

GROUP ADDR PORT CHIP NUM NAME START
gpio0 gpio@03020000 porta gpiochip0 480-511 XGPIOA 480 - XGPIOA[0]
gpio1 gpio@03021000 portb gpiochip1 448-479 XGPIOB 448 - XGPIOB[0]
gpio2 gpio@03022000 portc gpiochip2 416-447 XGPIOC 416 - XGPIOC[0]
gpio3 gpio@03023000 portd gpiochip3 384-415
gpio4 gpio@05021000 porte gpiochip4 352-383 PWR_GPIO 352 - PWR_GPIO[0]

Setting GPIOs

Example A28 (gpiochip0 line 28)

debian@duos:~$ sudo gpioset gpiochip0 28=1
debian@duos:~$ sudo gpioset gpiochip0 28=0

To enable ´$USER´ (e.g. debian in my case) to have read/write access to GPIO group 0, I did

sudo addgroup gpio
sudo usermod -a -G gpio debian
sudo chown root.gpio /dev/gpiochip0
sudo chmod g+rw /dev/gpiochip0

The members of group gpio can now read/write to the GPIOs in gpio0 (i.e. gpioset gpiochip0 28=0 without root permissions)

Manipulating GPIOs in Python

See also this documentation gpiod · PyPI

First made sure python3-dev was install

sudo apt install python3-dev

then I switched over to a python venv and installed gpiod

mkdir pyvenv
cd pyvenv
python3 -m venv .venv
source .venv/bin/activate
pip install gpiod

I then created the following example script (simple_gpio.py)

import time
import gpiod

A18, A19, A20, A28 = 18, 19, 20, 28
lines = [A18, A19, A20, A28]
chip_path = "/dev/gpiochip0"
cons = "example"

gpios=gpiod.request_lines(chip_path,consumer=cons,config={
  tuple(lines): gpiod.LineSettings(
    direction=gpiod.line.Direction.OUTPUT,
    output_value=gpiod.line.Value.INACTIVE)
})

for line in lines:
  gpios.set_value(line, gpiod.line.Value.ACTIVE)
  time.sleep(1)
  gpios.set_value(line, gpiod.line.Value.INACTIVE)

running it produces the expected outcome

1 Like

Hello Jonathon,

Thank you for the reply. But there is no Debian image for Milk-V Duo since it doesn’t have enough ram (based on what is written on their page). I think the solution to my problem is either I build a Linux image with buildroot and choose what packages to install or I use sysfs virtual file system.

Update:
Using sysfs is one of the ways to interact with the GPIO. Another library that could be used in the WiringX library. In order to use it I have to compile it using the Milk-V sdk and then copy the compiled file to the Milk-V duo using ssh and then I am able to run it.