private void Initialize() { if (_registerViewPointer != null) { return; } lock (s_InitializationLock) { if (_registerViewPointer != null) { return; } int fileDescriptor = Interop.open(GpioMemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor < 0) { throw new IOException("Error initializing the Gpio driver."); } IntPtr mapPointer = Interop.mmap(IntPtr.Zero, Environment.SystemPageSize, (MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE), MemoryMappedFlags.MAP_SHARED, fileDescriptor, GpioRegisterOffset); if (mapPointer.ToInt32() < 0) { throw new IOException("Error initializing the Gpio driver."); } Interop.close(fileDescriptor); _registerViewPointer = (RegisterView *)mapPointer; } }
private void Initialize() { if (_registerViewPointer != null) { return; } int fileDescriptor = open(GpioMemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor < 0) { throw Utils.CreateIOException("Error initializing Gpio driver", fileDescriptor); } //Console.WriteLine($"file descriptor = {fileDescriptor}"); IntPtr mapPointer = mmap(IntPtr.Zero, Environment.SystemPageSize, MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE, MemoryMappedFlags.MAP_SHARED, fileDescriptor, GpioBaseOffset); if (mapPointer.ToInt32() < 0) { throw Utils.CreateIOException("Error initializing Gpio driver", mapPointer.ToInt32()); } //Console.WriteLine($"mmap returned address = {mapPointer.ToInt32():X16}"); close(fileDescriptor); _registerViewPointer = (RegisterView *)mapPointer; _pinsToDetectEvents = new BitArray(PinCount); _debounceTimeouts = new TimeSpan[PinCount]; _lastEvents = new DateTime[PinCount]; }
public override void Dispose() { if (_registerViewPointer != null) { munmap((IntPtr)_registerViewPointer, 0); _registerViewPointer = null; } }
public override void Dispose() { _pinsToDetectEventsCount = 0; if (_registerViewPointer != null) { munmap((IntPtr)_registerViewPointer, 0); _registerViewPointer = null; } }
protected override void Dispose(bool disposing) { if (_registerViewPointer != null) { Interop.munmap((IntPtr)_registerViewPointer, 0); _registerViewPointer = null; } if (_sysFSDriver != null) { _sysFSDriver.Dispose(); _sysFSDriver = null; } }
private void Initialize() { if (_registerViewPointer != null) { return; } int fileDescriptor = open(GpioMemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor < 0) { throw new GpioException($"open error number: {Marshal.GetLastWin32Error()}"); } //Console.WriteLine($"file descriptor = {fileDescriptor}"); IntPtr mapPointer = mmap(IntPtr.Zero, Environment.SystemPageSize, MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE, MemoryMappedFlags.MAP_SHARED, fileDescriptor, GpioBaseOffset); if (mapPointer.ToInt32() < 0) { throw new GpioException($"mmap error number: {Marshal.GetLastWin32Error()}"); } //Console.WriteLine($"mmap returned address = {mapPointer.ToInt32():X16}"); close(fileDescriptor); _registerViewPointer = (RegisterView *)mapPointer; _lastEvent = new DateTime[PinCount]; _pinsToDetectEvents = new BitArray(PinCount); _eventDetectionThread = new Thread(DetectEvents) { IsBackground = true }; }
private void Initialize() { uint gpioRegisterOffset = 0; int fileDescriptor; int win32Error; if (_registerViewPointer != null) { return; } lock (s_initializationLock) { if (_registerViewPointer != null) { return; } // try and open /dev/gpiomem fileDescriptor = Interop.open(GpioMemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor == -1) { win32Error = Marshal.GetLastWin32Error(); // if the failure is NOT because /dev/gpiomem doesn't exist then throw an exception at this point. // if it were anything else then it is probably best not to try and use /dev/mem on the basis that // it would be better to solve the issue rather than use a method that requires root privileges if (win32Error != ENOENT) { throw new IOException($"Error {win32Error} initializing the Gpio driver."); } // if /dev/gpiomem doesn't seem to be available then let's try /dev/mem fileDescriptor = Interop.open(MemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()} initializing the Gpio driver."); } else // success so set the offset into memory of the gpio registers { gpioRegisterOffset = InvalidPeripheralBaseAddress; try { // get the periphal base address from the libbcm_host library which is the reccomended way // according to the RasperryPi website gpioRegisterOffset = Interop.libbcmhost.bcm_host_get_peripheral_address(); // if we get zero back then we use our own internal method. This can happen // on a Pi4 if the userland libraries haven't been updated and was fixed in Jul/Aug 2019. if (gpioRegisterOffset == 0) { gpioRegisterOffset = GetPeripheralBaseAddress(); } } catch (DllNotFoundException) { // if the code gets here then then use our internal method as libbcm_host isn't available. gpioRegisterOffset = GetPeripheralBaseAddress(); } if (gpioRegisterOffset == InvalidPeripheralBaseAddress) { throw new InvalidOperationException("Error - Unable to determine peripheral base address."); } // add on the offset from the peripheral base address to point to the gpio registers gpioRegisterOffset += GpioPeripheralOffset; } } IntPtr mapPointer = Interop.mmap(IntPtr.Zero, Environment.SystemPageSize, (MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE), MemoryMappedFlags.MAP_SHARED, fileDescriptor, (int)gpioRegisterOffset); if (mapPointer.ToInt64() == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()} initializing the Gpio driver."); } Interop.close(fileDescriptor); _registerViewPointer = (RegisterView *)mapPointer; // Detect whether we're running on a Raspberry Pi 4 IsPi4 = false; try { if (File.Exists(ModelFilePath)) { string model = File.ReadAllText(ModelFilePath, Text.Encoding.ASCII); if (model.Contains("Raspberry Pi 4")) { IsPi4 = true; } } } catch (Exception x) { // This should not normally fail, but we currently don't know how this behaves on different operating systems. Therefore, we ignore // any exceptions in release and just continue as Pi3 if something fails. // If in debug mode, we might want to check what happened here (i.e unsupported OS, incorrect permissions) Debug.Fail($"Unexpected exception: {x}"); } } }
private void Initialize() { uint gpioRegisterOffset = 0; int fileDescriptor; int win32Error; if (_registerViewPointer != null) { return; } lock (s_initializationLock) { if (_registerViewPointer != null) { return; } // try and open /dev/gpiomem fileDescriptor = Interop.open(GpioMemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor == -1) { win32Error = Marshal.GetLastWin32Error(); // if the failure is NOT because /dev/gpiomem doesn't exist then throw an exception at this point. // if it were anything else then it is probably best not to try and use /dev/mem on the basis that // it would be better to solve the issue rather than use a method that requires root privileges if (win32Error != ENOENT) { throw new IOException($"Error {win32Error} initializing the Gpio driver."); } // if /dev/gpiomem doesn't seem to be available then let's try /dev/mem fileDescriptor = Interop.open(MemoryFilePath, FileOpenFlags.O_RDWR | FileOpenFlags.O_SYNC); if (fileDescriptor == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()} initializing the Gpio driver."); } else // success so set the offset into memory of the gpio registers { gpioRegisterOffset = InvalidPeripheralBaseAddress; try { // get the periphal base address from the libbcm_host library which is the reccomended way // according to the RasperryPi website gpioRegisterOffset = Interop.libbcmhost.bcm_host_get_peripheral_address(); // if we get zero back then we use our own internal method. This can happen // on a Pi4 if the userland libraries haven't been updated and was fixed in Jul/Aug 2019. if (gpioRegisterOffset == 0) { gpioRegisterOffset = GetPeripheralBaseAddress(); } } catch (DllNotFoundException) { // if the code gets here then then use our internal method as libbcm_host isn't available. gpioRegisterOffset = GetPeripheralBaseAddress(); } if (gpioRegisterOffset == InvalidPeripheralBaseAddress) { throw new InvalidOperationException("Error - Unable to determine peripheral base address."); } // add on the offset from the peripheral base address to point to the gpio registers gpioRegisterOffset += GpioPeripheralOffset; } } IntPtr mapPointer = Interop.mmap(IntPtr.Zero, Environment.SystemPageSize, (MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE), MemoryMappedFlags.MAP_SHARED, fileDescriptor, (int)gpioRegisterOffset); if (mapPointer.ToInt64() == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()} initializing the Gpio driver."); } Interop.close(fileDescriptor); _registerViewPointer = (RegisterView *)mapPointer; } }