diff --git a/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3Driver.cs b/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3Driver.cs index 6d59312f9a6b2c92a1dc1637575da4414608aa3c..712baa8bcdabc99dd4ae23e47caf163dbd83182d 100644 --- a/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3Driver.cs +++ b/src/System.Device.Gpio/System/Device/Gpio/Drivers/RaspberryPi3Driver.cs @@ -41,7 +41,7 @@ namespace System.Device.Gpio.Drivers } else { - _internalDriver = new Windows10Driver(); + _internalDriver = CreateWindows10GpioDriver(); _setSetRegister = (value) => throw new PlatformNotSupportedException(); _setClearRegister = (value) => throw new PlatformNotSupportedException(); _getSetRegister = () => throw new PlatformNotSupportedException(); @@ -49,6 +49,16 @@ namespace System.Device.Gpio.Drivers } } + [MethodImpl(MethodImplOptions.NoInlining)] + private static GpioDriver CreateWindows10GpioDriver() + { + // This wrapper is needed to prevent Mono from loading Windows10Driver + // which causes all fields to be loaded - one of such fields is WinRT type which does not + // exist on Linux which causes TypeLoadException. + // Using NoInlining and no explicit type prevents this from happening. + return new Windows10Driver(); + } + /// protected internal override int PinCount => 28; diff --git a/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs b/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs index a3155c0c086d05dd82c5ffdeffb3f9677c996def..bb045fa7b32b8c991c02749eb1a1a7db18f764f4 100644 --- a/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs +++ b/src/System.Device.Gpio/System/Device/I2c/I2cDevice.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Runtime.CompilerServices; + namespace System.Device.I2c { /// @@ -67,7 +69,7 @@ namespace System.Device.I2c { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - return new Windows10I2cDevice(settings); + return CreateWindows10I2cDevice(settings); } else { @@ -75,6 +77,16 @@ namespace System.Device.I2c } } + [MethodImpl(MethodImplOptions.NoInlining)] + private static I2cDevice CreateWindows10I2cDevice(I2cConnectionSettings settings) + { + // This wrapper is needed to prevent Mono from loading Windows10I2cDevice + // which causes all fields to be loaded - one of such fields is WinRT type which does not + // exist on Linux which causes TypeLoadException. + // Using NoInlining and no explicit type prevents this from happening. + return new Windows10I2cDevice(settings); + } + /// public void Dispose() { diff --git a/src/System.Device.Gpio/System/Device/Pwm/PwmChannel.cs b/src/System.Device.Gpio/System/Device/Pwm/PwmChannel.cs index 1bc98508e748849eafabd7a7843d290157b9aaa0..2f3014db0d24ba9dcce91feeda10d1bc8ab8a53a 100644 --- a/src/System.Device.Gpio/System/Device/Pwm/PwmChannel.cs +++ b/src/System.Device.Gpio/System/Device/Pwm/PwmChannel.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Runtime.CompilerServices; + namespace System.Device.Pwm { /// @@ -61,7 +63,7 @@ namespace System.Device.Pwm { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - return new Channels.Windows10PwmChannel( + return CreateWindows10PwmChannel( chip, channel, frequency, @@ -76,5 +78,19 @@ namespace System.Device.Pwm dutyCyclePercentage); } } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static PwmChannel CreateWindows10PwmChannel(int chip, int channel, int frequency, double dutyCyclePercentage) + { + // This wrapper is needed to prevent Mono from loading Windows10PwmChannel + // which causes all fields to be loaded - one of such fields is WinRT type which does not + // exist on Linux which causes TypeLoadException. + // Using NoInlining and no explicit type prevents this from happening. + return new Channels.Windows10PwmChannel( + chip, + channel, + frequency, + dutyCyclePercentage); + } } } diff --git a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs b/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs index 3edb5cc8996a9d22613b28d6a86e371996ef0fa7..8f262429904c57c1ded7cc1a3dbd75a1199d66c4 100644 --- a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs +++ b/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Runtime.CompilerServices; + namespace System.Device.Spi { /// @@ -60,7 +62,7 @@ namespace System.Device.Spi { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - return new Windows10SpiDevice(settings); + return CreateWindows10SpiDevice(settings); } else { @@ -68,6 +70,16 @@ namespace System.Device.Spi } } + [MethodImpl(MethodImplOptions.NoInlining)] + private static SpiDevice CreateWindows10SpiDevice(SpiConnectionSettings settings) + { + // This wrapper is needed to prevent Mono from loading Windows10SpiDevice + // which causes all fields to be loaded - one of such fields is WinRT type which does not + // exist on Linux which causes TypeLoadException. + // Using NoInlining and no explicit type prevents this from happening. + return new Windows10SpiDevice(settings); + } + /// public void Dispose() {