GPIO and sysfs

I was recently working on a project where some gpio pins were being toggled from within the user space:

const char *const amplifierGPIO = "/sys/class/gpio/gpio107/value";

    void amplifierUnmute()
    {
      std::ofstream amp(amplifierGPIO);
      if (amp.is_open())
      {
        amp << "1";
        amp.close();
      }
    }

Now I am wondering how this works. For instance, is there some file where every pin which has been instantiated as a gpio pin is listed s/t the a user can access it like in the example above. Or does one have to go beyond instantiating the pin as gpio? For instance, lets say I build a pin as a gpio:

MX51_PIN_EIM_A24 = _MXC_BUILD_GPIO_PIN_MX51(1, 18, 1, 0xBC, 0x450),

Now how to access that pin inside the user space... it doesn't seem obvious to me how to go from instantiating a pin as a gpio pin to accessing it from the user space. It also seems foolish to believe that it is hard. I am going to start with this kernels Documentation/gpio.txt

The /sys/ is an interface to the kernel (that resides in memory). A device driver, when loaded by the kernel, can plug into the /sys/ tree.
It depends on the driver how this is done. For example it can group items in a "sub folder"; and it can show an item read-only or implement it as change-able.
Most device drivers present each item like a file, having a one-value contents.
Yes, you really have to consult the driver documentation.

1 Like

I'd change your code slightly:

    void amplifierUnmute()
    {
      std::ofstream amp(amplifierGPIO);
      if (amp.is_open()) amp << "1" << endl;
    }

I'm not completely sure the newline is necessary but that's how I've always seen data written to /sys/, and it will prevent iostream from holding the data in buffer besides.

The close() is redundant, that happens automatically when amp goes out of scope, which happens whenever amplifierUnmute() returns.

1 Like

@Corona688 Thanks I will be sure to change my code! So I did managed to figure out the gpio lib. Apparently there is a formula that the Linux kernel uses for identifying pins based on their GPIO number:

linux gpio number = (gpio_bank - 1) * 32 + gpio_bit

So if you're pin is: GPIO2_18, then in the Linux kernel that would be: (2-1)32+18 = 50

That is the number you would have to reference in order to toggle the pin from within the user space using gpiolib.

2 Likes