A Swift package for GPIO (General Purpose Input/Output) support on Linux systems.
This library is in early development (v0.0.1) and should be considered experimental. Use with caution in production environments. APIs may change between versions without notice. Thoroughly test your specific hardware configuration before deploying.
- 🚀 Swift 6.1 support with full concurrency
- 🐧 Linux GPIO sysfs interface
- 🔧 Simple and safe API with automatic resource management
- ⚡ Lightweight with no external dependencies
- 🧪 Comprehensive test suite using Swift Testing
- Swift 6.1+
- Linux (tested on Ubuntu, Raspberry Pi OS, JetPack)
- Root privileges for GPIO operations
- Pi Zero 2W: GPIO pins 0-27 (40-pin header)
- Pi 4: GPIO pins 0-27 (40-pin header)
- Pi 5: GPIO pins 0-27 (40-pin header)
Uses BCM GPIO numbering (not physical pin numbers).
- Jetson Orin Nano: 40-pin header compatible with Pi pinout
- Uses different GPIO numbering than Raspberry Pi
- Check
/sys/kernel/debug/gpioorjetson-gpiodocumentation for pin mapping
Any Linux system with GPIO sysfs interface support (/sys/class/gpio/)
Add GPIO to your Package.swift dependencies:
dependencies: [
.package(url: "https://github.com/edgeengineer/gpio.git", from: "0.0.1")
]Then add it to your target:
targets: [
.target(
name: "YourTarget",
dependencies: ["GPIO"]
)
]import GPIO
do {
// Raspberry Pi: Initialize GPIO pin 18 as output (BCM numbering)
let gpio = try GPIO(pin: 18, direction: .output)
// Jetson Orin Nano: Use Jetson GPIO numbering
// let gpio = try GPIO(pin: 422, direction: .output) // Example GPIO number
// Set pin high
gpio.value = .high
// Set pin low
gpio.value = .low
// Toggle pin state
try gpio.toggle()
// Clean up when done.
// Note: Cleanup is also handled automatically when the GPIO object is deallocated.
try gpio.cleanup()
} catch {
print("GPIO Error: \(error)")
}import GPIO
do {
// Raspberry Pi: Initialize GPIO pin 23 as input (BCM numbering)
let gpio = try GPIO(pin: 23, direction: .input)
// Jetson Orin Nano: Use appropriate GPIO number for your pin
// let gpio = try GPIO(pin: 424, direction: .input) // Example GPIO number
// Read current value
let value = try gpio.value
print("Pin value is: \(value == .high ? "HIGH" : "LOW")")
// Clean up
// Note: Cleanup is also handled automatically when the GPIO object is deallocated.
try gpio.cleanup()
} catch {
print("GPIO Error: \(error)")
}init(pin: Int, direction: GPIODirection)- Initializes, exports, and configures the GPIO pin.
var direction: GPIODirection- Get or set the pin's direction (input/output).var value: GPIOValue- Get or set the pin's value (high/low).
toggle()- Toggle pin state from high to low or low to high.cleanup()- Manually unexport the pin.
.input- Configure pin as input.output- Configure pin as output
.low- Low state (0V).high- High state (3.3V/5V)
.exportFailed- Failed to export pin.unexportFailed- Failed to unexport pin.directionSetFailed- Failed to set direction.valueFailed- Failed to read/write value.invalidPin- Invalid pin number.fileSystemError(String)- File system operation failed, contains a descriptive error..notSupported- Platform not supported
GPIO operations require root privileges. Run your application with sudo:
sudo swift runOr set up udev rules for non-root access:
# Add to /etc/udev/rules.d/99-gpio.rules
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"Run the test suite:
swift testNote: Some tests require Linux and root privileges to fully test GPIO functionality.
Use BCM GPIO numbering. Common pins:
- Physical pin 7 = BCM GPIO 4
- Physical pin 11 = BCM GPIO 17
- Physical pin 12 = BCM GPIO 18
- Physical pin 13 = BCM GPIO 27
Check GPIO mapping with:
# View all GPIO information
sudo cat /sys/kernel/debug/gpio
# Check available GPIO chips
ls /sys/class/gpio/
# Find specific pin mapping
# Physical pin 7 might be GPIO 422 (example)
# Physical pin 11 might be GPIO 424 (example)Consult the Jetson Orin Nano Developer Kit pinout for accurate GPIO numbers.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Built for the Swift on Linux ecosystem
- Inspired by the need for simple GPIO control in Swift applications
- Uses Linux sysfs GPIO interface for maximum compatibility