Search code examples
.netubuntutestingvirtualgpio

How to setup virtual Gpio loopback


I'm currently working on a program which should use a gpio pin in .Net. I wanted to test my program on virtual gpio pin but i don't know how to do it.

I wanted to do a loopback where a virtual gpio 1 would be connected to another virtual gpio 2.

I've already done something similar with serial port and tty0tty.

Also, i'm on Ubuntu.


Solution

  • If there is no real hardware available to you, there is no such possibility without hacking a real kernel driver. Luckily in the Linux kernel we have gpio-mockup (and new coming gpio-sim) which is used for testing GPIO library and APIs.

    The main idea is that. You create a virtual GPIO chip:

    % modprobe gpio-mockup gpio_mockup_ranges=-1,3 gpio_mockup_named_lines
    
    % gpiodetect
    ...
    gpiochip2 [gpio-mockup-A] (3 lines)
    
    % gpioinfo 2
    gpiochip2 - 3 lines:
            line   0: "gpio-mockup-A-0" unused input active-high 
            line   1: "gpio-mockup-A-1" unused input active-high 
            line   2: "gpio-mockup-A-2" unused input active-high 
    

    Through DebugFS you may see the lines as being on the hardware side, i.e. whatever you write there, the Linux stack will consider as a state of hardware:

    % mount -t debugfs none /sys/kernel/debug
    
    % ls -l /sys/kernel/debug/gpio-mockup/gpiochip2/
    total 0
    --w-------    1 root     root             0 Jan 29 01:10 0
    --w-------    1 root     root             0 Jan 29 01:10 1
    --w-------    1 root     root             0 Jan 29 01:10 2
    
    

    (Note write-only attribute there)

    Now demo part

    Check first the current state of a pin (let's choose pin 2 of that virtual GPIO controller):

    % gpioget 2 2
    0
    

    Let's assume the hardware state of the pin has been changed from 0 to 1:

    % echo 1 > /sys/kernel/debug/gpio-mockup/gpiochip2/2
    

    Check the state of the pin again:

    % gpioget 2 2
    1
    

    For the output part it's a bit complicated, i.e. either you need deprecated sysfs interface to the GPIO chip or you have to run a thread or fork a process from your code to keep the context state correct. With gpioget and gpioset it's currently impossible because the driver restores the state immediately after device node (of the GPIO controller) is closed.

    Overall I think you got the idea and maybe you even don't need an output GPIO line.