Raspberry Pi gpio via mmap

CS 301: Assembly Language Programming Lecture, Dr. Lawlor

Almost all hardware devices show up in physical memory somewhere. 

Raspberry Pi 2 pinout

On the Raspberry Pi single-board ARM computer, the external pins called general-purpose input/output (GPIO) pins are accessible to the CPU as a range of physical memory addresses.


GPIO Chip
First GPIO Physical Address
(in /dev/mem)
Raspberry Pi 1
BCM2835
0x20200000
Raspberry Pi 2
BCM2836 0x3F200000
Future Pis
???
???

Because the addresses move, and because /dev/mem direct physical memory access requires root permissions, there is a simpler interface file /dev/gpiomem, which always starts at the GPIO base addresses.  Either way, to use them you open the file, and mmap the hardware's physical addresses into your program's memory space, then directly access the gpio pins by reading and writing that memory.

#include <stdio.h>    // for printf
#include <fcntl.h>    // for open
#include <sys/mman.h> // for mmap
#include <unistd.h> 

long foo(void) 
{
	int fdgpio=open("/dev/gpiomem",O_RDWR);
	if (fdgpio<0) { printf("Error opening /dev/gpiomem"); return -1; }

	unsigned int *gpio=(unsigned int *)mmap(0,4096,
		PROT_READ+PROT_WRITE, MAP_SHARED,
		fdgpio,0);
	printf("mmap'd gpiomem at pointer %p\n",gpio);
	
	// Read pin 8, by accessing bit 8 of GPLEV0
	return gpio[13]&(1<<8);
}

(Try this in NetRun now!)


Once you've found the GPIO chip, you read and write the chip's registers by reading and writing memory there.   This table is a distilled version of the BCM2835 documentation, chapter 6.

Name
Purpose
Byte Offset
Int Offset
GPLEV0
In input mode, each bit reads one GPIO pin.
0x34
gpio[13]
GPSET0
In output mode, turn a GPIO pin high by writing the corresponding bit here. 
E.g., GPIO pin 8 is bit 1<<8, so you set it with gpio[7]=1<<8;
0x1C
gpio[7]
GPCLR0
In output mode, turn a GPIO pin low by writing the corresponding bit here.
0x28
gpio[10]
GPFSEL0
Sets the mode for the first 10 I/O pins, numbers 0..9.  Each pin has a 3-bit field, with 000 meaning input, 001 meaning output, and 010 and higher meaning "alternate functions" specific to each pin (see chapter 6.2).
0
gpio[0]
GPFSEL1
Sets the mode for the next 10 I/O pins, numbers 10..19.
4
gpio[1]