Search code examples
c#monoraspberry-pi3raspbian

(Raspbian + C# + Mono) Type initializer for 'System.Device.Gpio.Drivers.LibGpiodDriver' threw an exception


I'm conducting a preliminary study for a new project. I've purchased a Raspberry Pi 3B and I'm trying to run a small program to check all our requisites:

  1. SQL Server connection.
  2. Save configuration files on disk.
  3. Configure and use some DI/DO in Raspberry GPIO.

By now I've installed Mono libraries on it and I'm using Visual Studio 2019 in my windows machine to build a WinForms application.

Raspberry OS version: Raspbian GNU/Linux 10 (buster)
Mono version        : Mono JIT compiler version 6.12.0.122

And these are the packages of my application: (.Net Framework 4.8)

<packages>
  <package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net48" />
  <package id="System.Buffers" version="4.5.1" targetFramework="net48" />
  <package id="System.Device.Gpio" version="1.5.0" targetFramework="net48" />
  <package id="System.Memory" version="4.5.4" targetFramework="net48" />
  <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net48" />
  <package id="System.Runtime.InteropServices.WindowsRuntime" version="4.3.0" targetFramework="net48" />
  <package id="System.Runtime.WindowsRuntime" version="4.6.0" targetFramework="net48" />
  <package id="System.Security.AccessControl" version="5.0.0" targetFramework="net48" />
  <package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net48" />
  <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
</packages>

By now I have nothing connected to the GPIO, I'm just trying to read a pin value using this code:

private void ReadPinTest()
{
    int pin = 24;
    PinValue pinValue = PinValue.Low;

    try
    {
        using (GpioController gpio = new GpioController(PinNumberingScheme.Board))
        {
            if (gpio == null)
            {
                MessageBox.Show("No GPIO controller found.");
                return;
            }

            gpio.OpenPin(pin, PinMode.Input);
            pinValue = gpio.Read(pin);
        }

        MessageBox.Show($"Pin {pin} is {pinValue}");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        MessageBox.Show(ex.InnerException.Message);
        MessageBox.Show(ex.InnerException.StackTrace);
    }
}

And I'm getting next errors:

Exception message:

Type initializer for 'System.Device.Gpio.Drivers.LibGpiodDriver' threw an exception.

InnerException message:

libgpiod

InnerException StackTrace:

at(wrapper managed - to - native) Interop + libgpiod.gpiod_version_string()
at System.Device.Gpio.Drivers.LibGpiodDriver.IsLibgpiodVersion1_5orHigher() [0x00000] in < d49ca6cd97194f038905958dbca2c58c >:0
at System.Device.Gpio.Drivers.LibGpiodDriver..cctor ()[0x0000f] in :0

I've tried by reinstalling gpiod libraries:

sudo apt-get install gpiod

gpiod is already the newest version (1.2-3+rpi1).

What am I doing wrong?


Solution

  • I recommend using .NET 5.0 when targeting linux/raspbian. The support for linux has been greatly improved in this version, while the future of Mono is uncertain. It does not officially have Gui support yet, but you can either use Avalonia or try the Maui-Linux package, which will eventually make it into .NET 6.0 (which is scheduled for this fall).

    Your particular problem is probably solved by running

    sudo apt install -y libgpiod-dev
    

    However, System.Device.Gpio has not been deeply tested against mono, because it is mostly targeting .NET Core. .NET Framework support is for Windows.