树霉pi gpio内存映射
/dev/mem 需root权限
/dev/gpiomem 不需要
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#define BCM2837_PERI_BASE 0x3F000000
#define BCM2835_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2835_PERI_BASE + 0x200000)
#define PAGE_SIZE 4096
int main() {
char* fname = "/dev/gpiomem";
int fd = open(fname,O_RDWR);
printf("fd = %d\n", fd);
unsigned int * adr = mmap(0,PAGE_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,fd,GPIO_BASE);
printf("gpio addr %p\n",adr);
// manipulate
munmap(adr,PAGE_SIZE);
close(fd);
}
闪烁自带led
gpio16
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#define BCM2837_PERI_BASE 0x3F000000
#define BCM2835_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2835_PERI_BASE + 0x200000)
#define PAGE_SIZE 4096
// int offset 4byte
#define SEL0 0 //gpio0-9
#define SEL1 1 //gpio10-19
#define SET0 7
#define SET1 8
#define CLR0 10
#define CLR1 11
#define LEDPIN 16 // builtin status led pin gpio num
int main() {
char* fname = "/dev/gpiomem";
int fd = open(fname,O_RDWR);
printf("fd = %d\n", fd);
uint32_t* adr = mmap(0,PAGE_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,fd,GPIO_BASE);
printf("gpio addr %p\n",adr);
unsigned int offset = LEDPIN / 10;
unsigned int shift = (LEDPIN % 10) * 3;
*(adr + SEL0 + offset) &= ~(0x7<< shift); //clear gpio 16 mode (16-10)*3
*(adr + SEL0 + offset) |= (1 << shift); // set gpio 16 as output
offset = LEDPIN /32;
shift = LEDPIN % 32;
for(int i = 0; i < 10; i++) {
*(adr+SET0 +offset) = (1 << shift); // set gpio16 1
usleep(300*1000);
*(adr+CLR0 +offset) = (1 << shift); // set gpio16 0
usleep(300*1000);
}
munmap(adr,PAGE_SIZE);
close(fd);
}