未验证 提交 b135f814 编写于 作者: J Jose Perez Rodriguez 提交者: GitHub

Bind to explicit major version of libgpiod (#2120)

上级 79a8bcdd
......@@ -17,9 +17,9 @@ internal class SafeChipHandle : SafeHandle
protected override bool ReleaseHandle()
{
Interop.libgpiod.gpiod_chip_close(handle);
Interop.Libgpiod.gpiod_chip_close(handle);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero || handle == Interop.libgpiod.InvalidHandleValue;
public override bool IsInvalid => handle == IntPtr.Zero || handle == Interop.Libgpiod.InvalidHandleValue;
}
......@@ -17,9 +17,9 @@ internal class SafeChipIteratorHandle : SafeHandle
protected override bool ReleaseHandle()
{
Interop.libgpiod.gpiod_chip_iter_free(handle);
Interop.Libgpiod.gpiod_chip_iter_free(handle);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero || handle == Interop.libgpiod.InvalidHandleValue;
public override bool IsInvalid => handle == IntPtr.Zero || handle == Interop.Libgpiod.InvalidHandleValue;
}
......@@ -20,17 +20,17 @@ internal class SafeLineHandle : SafeHandle
protected override bool ReleaseHandle()
{
// Contrary to intuition, this does not invalidate the handle (see comment on declaration)
Interop.libgpiod.gpiod_line_release(handle);
Interop.Libgpiod.gpiod_line_release(handle);
return true;
}
/// <summary>
/// Release the lock on the line handle. <see cref="Interop.libgpiod.gpiod_line_release"/>
/// Release the lock on the line handle. <see cref="Interop.Libgpiod.gpiod_line_release"/>
/// </summary>
public void ReleaseLock()
{
ReleaseHandle();
}
public override bool IsInvalid => handle == IntPtr.Zero || handle == Interop.libgpiod.InvalidHandleValue;
public override bool IsInvalid => handle == IntPtr.Zero || handle == Interop.Libgpiod.InvalidHandleValue;
}
......@@ -8,15 +8,48 @@
using System;
using System.Device.Gpio;
using System.Runtime.InteropServices;
#if NET6_0_OR_GREATER
using System.Runtime.Loader;
using System.Reflection;
#endif
// Since this is only used on Linux, and in C on Linux sizeof(long) == sizeof(void*) this is a valid alias.
using NativeLong = System.IntPtr;
internal partial class Interop
{
internal partial class libgpiod
internal static partial class Libgpiod
{
#if NET6_0_OR_GREATER
private const string LibgpiodLibrary = "libgpiod.so.2";
#else
private const string LibgpiodLibrary = "libgpiod";
internal static IntPtr InvalidHandleValue = new IntPtr(-1);
#endif
internal static IntPtr InvalidHandleValue;
static Libgpiod()
{
InvalidHandleValue = new IntPtr(-1);
#if NET6_0_OR_GREATER
Assembly currentAssembly = typeof(Libgpiod).Assembly;
AssemblyLoadContext.GetLoadContext(currentAssembly)!.ResolvingUnmanagedDll += (assembly, libgpiodName) =>
{
if (assembly != currentAssembly || libgpiodName != LibgpiodLibrary)
{
return IntPtr.Zero;
}
// If loading the 2.x libgpiod failed, we may be running in a Linux distribution that has the 1.x
// version installed, so we try to load that instead.
if (NativeLibrary.TryLoad("libgpiod.so.1", out IntPtr handle))
{
return handle;
}
return IntPtr.Zero;
};
#endif
}
/// <summary>
/// Release all resources allocated for the gpiochip iterator and close the most recently opened gpiochip(if any).
......
......@@ -31,7 +31,7 @@ public class LibGpiodDriver : UnixDriver
// for use the bias flags we need libgpiod version 1.5 or later
private static bool IsLibgpiodVersion1_5orHigher()
{
IntPtr libgpiodVersionPtr = Interop.libgpiod.gpiod_version_string();
IntPtr libgpiodVersionPtr = Interop.Libgpiod.gpiod_version_string();
string? libgpiodVersionMatch = Marshal.PtrToStringAnsi(libgpiodVersionPtr);
if (libgpiodVersionMatch is object)
......@@ -69,13 +69,13 @@ public class LibGpiodDriver : UnixDriver
try
{
_pinNumberLock = new object();
_chip = Interop.libgpiod.gpiod_chip_open_by_number(gpioChip);
_chip = Interop.Libgpiod.gpiod_chip_open_by_number(gpioChip);
if (_chip == null)
{
throw ExceptionHelper.GetIOException(ExceptionResource.NoChipFound, Marshal.GetLastWin32Error());
}
_pinCount = Interop.libgpiod.gpiod_chip_num_lines(_chip);
_pinCount = Interop.Libgpiod.gpiod_chip_num_lines(_chip);
_pinNumberToEventHandler = new ConcurrentDictionary<int, LibGpiodDriverEventHandler>();
_pinNumberToSafeLineHandle = new ConcurrentDictionary<int, SafeLineHandle>();
_pinValue = new ConcurrentDictionary<int, PinValue>();
......@@ -115,10 +115,10 @@ public class LibGpiodDriver : UnixDriver
{
_pinNumberToSafeLineHandle.TryGetValue(pinNumber, out SafeLineHandle? pinHandle);
if (pinHandle is null || (pinHandle is object && !Interop.libgpiod.gpiod_line_is_free(pinHandle)))
if (pinHandle is null || (pinHandle is object && !Interop.Libgpiod.gpiod_line_is_free(pinHandle)))
{
pinHandle?.Dispose();
pinHandle = Interop.libgpiod.gpiod_chip_get_line(_chip, pinNumber);
pinHandle = Interop.Libgpiod.gpiod_chip_get_line(_chip, pinNumber);
_pinNumberToSafeLineHandle[pinNumber] = pinHandle;
}
......@@ -184,13 +184,13 @@ public class LibGpiodDriver : UnixDriver
return;
}
SafeLineHandle pinHandle = Interop.libgpiod.gpiod_chip_get_line(_chip, pinNumber);
SafeLineHandle pinHandle = Interop.Libgpiod.gpiod_chip_get_line(_chip, pinNumber);
if (pinHandle == null)
{
throw ExceptionHelper.GetIOException(ExceptionResource.OpenPinError, Marshal.GetLastWin32Error());
}
int mode = Interop.libgpiod.gpiod_line_direction(pinHandle);
int mode = Interop.Libgpiod.gpiod_line_direction(pinHandle);
if (mode == 1)
{
pinHandle.PinMode = PinMode.Input;
......@@ -202,7 +202,7 @@ public class LibGpiodDriver : UnixDriver
if (s_isLibgpiodVersion1_5orHigher && pinHandle.PinMode == PinMode.Input)
{
int bias = Interop.libgpiod.gpiod_line_bias(pinHandle);
int bias = Interop.Libgpiod.gpiod_line_bias(pinHandle);
if (bias == (int)RequestFlag.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
{
pinHandle.PinMode = PinMode.InputPullDown;
......@@ -226,7 +226,7 @@ public class LibGpiodDriver : UnixDriver
{
if (_pinNumberToSafeLineHandle.TryGetValue(pinNumber, out SafeLineHandle? pinHandle))
{
int result = Interop.libgpiod.gpiod_line_get_value(pinHandle);
int result = Interop.Libgpiod.gpiod_line_get_value(pinHandle);
if (result == -1)
{
throw ExceptionHelper.GetIOException(ExceptionResource.ReadPinError, Marshal.GetLastWin32Error(), pinNumber);
......@@ -271,12 +271,12 @@ public class LibGpiodDriver : UnixDriver
pinHandle.ReleaseLock();
int requestResult = mode switch
{
PinMode.Input => Interop.libgpiod.gpiod_line_request_input(pinHandle, s_consumerName),
PinMode.InputPullDown => Interop.libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
PinMode.Input => Interop.Libgpiod.gpiod_line_request_input(pinHandle, s_consumerName),
PinMode.InputPullDown => Interop.Libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
(int)RequestFlag.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN),
PinMode.InputPullUp => Interop.libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
PinMode.InputPullUp => Interop.Libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
(int)RequestFlag.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP),
PinMode.Output => Interop.libgpiod.gpiod_line_request_output(pinHandle, s_consumerName, 0),
PinMode.Output => Interop.Libgpiod.gpiod_line_request_output(pinHandle, s_consumerName, 0),
_ => -1,
};
......@@ -303,12 +303,12 @@ public class LibGpiodDriver : UnixDriver
pinHandle.ReleaseLock();
int requestResult = mode switch
{
PinMode.Input => Interop.libgpiod.gpiod_line_request_input(pinHandle, s_consumerName),
PinMode.InputPullDown => Interop.libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
PinMode.Input => Interop.Libgpiod.gpiod_line_request_input(pinHandle, s_consumerName),
PinMode.InputPullDown => Interop.Libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
(int)RequestFlag.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN),
PinMode.InputPullUp => Interop.libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
PinMode.InputPullUp => Interop.Libgpiod.gpiod_line_request_input_flags(pinHandle, s_consumerName,
(int)RequestFlag.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP),
PinMode.Output => Interop.libgpiod.gpiod_line_request_output(pinHandle, s_consumerName, initialValue == PinValue.High ? 1 : 0),
PinMode.Output => Interop.Libgpiod.gpiod_line_request_output(pinHandle, s_consumerName, initialValue == PinValue.High ? 1 : 0),
_ => -1,
};
......@@ -383,7 +383,7 @@ public class LibGpiodDriver : UnixDriver
pin: pinNumber);
}
Interop.libgpiod.gpiod_line_set_value(pinHandle, (value == PinValue.High) ? 1 : 0);
Interop.Libgpiod.gpiod_line_set_value(pinHandle, (value == PinValue.High) ? 1 : 0);
_pinValue[pinNumber] = value;
}
......@@ -391,7 +391,7 @@ public class LibGpiodDriver : UnixDriver
public override ComponentInformation QueryComponentInformation()
{
var self = new ComponentInformation(this, "LibGpiodDriver");
IntPtr libgpiodVersionPtr = Interop.libgpiod.gpiod_version_string();
IntPtr libgpiodVersionPtr = Interop.Libgpiod.gpiod_version_string();
string libgpiodVersion = Marshal.PtrToStringAnsi(libgpiodVersionPtr) ?? string.Empty;
self.Properties["LibGpiodVersion"] = libgpiodVersion;
return self;
......
......@@ -34,7 +34,7 @@ internal sealed class LibGpiodDriverEventHandler : IDisposable
private void SubscribeForEvent(SafeLineHandle pinHandle)
{
int eventSuccess = Interop.libgpiod.gpiod_line_request_both_edges_events(pinHandle, s_consumerName);
int eventSuccess = Interop.Libgpiod.gpiod_line_request_both_edges_events(pinHandle, s_consumerName);
if (eventSuccess < 0)
{
......@@ -55,7 +55,7 @@ internal sealed class LibGpiodDriverEventHandler : IDisposable
TvNsec = new IntPtr(50_000_000)
};
WaitEventResult waitResult = Interop.libgpiod.gpiod_line_event_wait(pinHandle, ref timeout);
WaitEventResult waitResult = Interop.Libgpiod.gpiod_line_event_wait(pinHandle, ref timeout);
if (waitResult == WaitEventResult.Error)
{
var errorCode = Marshal.GetLastWin32Error();
......@@ -71,7 +71,7 @@ internal sealed class LibGpiodDriverEventHandler : IDisposable
if (waitResult == WaitEventResult.EventOccured)
{
GpioLineEvent eventResult = new GpioLineEvent();
int checkForEvent = Interop.libgpiod.gpiod_line_event_read(pinHandle, ref eventResult);
int checkForEvent = Interop.Libgpiod.gpiod_line_event_read(pinHandle, ref eventResult);
if (checkForEvent == -1)
{
throw ExceptionHelper.GetIOException(ExceptionResource.EventReadError, Marshal.GetLastWin32Error());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册