Raspberry Pi is based on Broadcom BCM2835 chip.
We can find description of Broadcom BCM2835 Peripherals here.
There are 54 general-purpose I/O (GPIO) lines split into two banks.
Here is instruction how to work with GPIO on Raspberry Pi with FreeBSD.
We can find good description of Raspberry Pi low-level peripherals here.
The production Raspberry Pi board has a 26-pin 2.54 mm expansion header, marked as P1, arranged in a 2×13 strip.
They provide 8 GPIO pins plus access to I²C, SPI, UART, as well as +3.3V, +5V and GND supply lines.
During the FreeBSD boot we can see messages about GPIO:
It sees 54 pins.
We can use gpioctl(1) utility to work with GPIO.
After boot some of pins are in IN status and some of them are in OUT status:
Let’s try to play with GPIO.
I connected LED to pin 23 for OUT and photocell to pin 25 for IN.
Usually we need to connect photocell to analog input, not to digital input.
But in our case we will get the rounded value: 0 without light and 1 with light.
I will light LED and check photocell status.
First we need to put pin 23 to OUT state.
Then we can change it status to HIGH (1) or LOW (0) value:
When we set the status of pin 23 to HIGHT (1) our LED will light:
Let’s play with pin 23 and check status of pin 25:
We can see that when turn LED (pin 23) on (gpioctl 23 1
) pin 25 returns HIGH (1 in last string).
And when we turn LED off (gpioctl 23 0
) pin 25 returns LOW (0 in last string).
We also can play with GPIO from C Languages.
Next small programm just put pin in OUT status and set in value to HIGH or LOW value (I used source code of gpioctl):
#include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <fcntl.h> #include <paths.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/gpio.h> void usage ( void ) { fprintf ( stderr, "Usage: pin [0|1]\n" ); exit(1); } int main ( int argc, char **argv ) { int pin, val, fd; char ctlfile[] = _PATH_DEVGPIOC "0"; struct gpio_pin gpiopin; struct gpio_req gpioreq; if ( argc != 3 ) usage(); sscanf( argv[1], "%d", &pin ); sscanf( argv[2], "%d", &val ); if ( (val != 0) && (val != 1) ) { fprintf ( stderr, "Invalid pin value: %d\n", val ); exit(1); } printf ( "pin .. %d, val .. %d\n", pin, val ); if ( (fd = open(ctlfile, O_RDONLY)) < 0 ) { perror("open"); exit(1); } gpiopin.gp_pin = pin; gpiopin.gp_flags = GPIO_PIN_OUTPUT; if ( ioctl(fd, GPIOSETCONFIG, &gpiopin) < 0 ) { perror("ioctl(GPIOSETCONFIG)"); exit(1); } gpioreq.gp_pin = pin; gpioreq.gp_value = val; if ( ioctl(fd, GPIOSET, &gpioreq) < 0 ) { perror("ioctl(GPIOSET)"); exit(1); } close(fd); exit(0); }
Thanks a lot for a good starting point! Is there an easy way to use gpioctl to continously read from a GPIO-pin as an unprivileged user?
We can use ‘sudo’ for that.
Hello Vadim,
Do you tray control GPIO-pin on Raspberry Pi 3 B+ ?
I have this device but gpioctl can change status of pin but fisical state don’t change
Hello.
No, I didn’t tried it yet. May be in near future.
Thank you for reply,
And thanks for sharing your experience,
It is very interesting!