通过/ dev / mem驱动Beaglebone GPIO [英] Driving Beaglebone GPIO through /dev/mem
问题描述
我正在为Beaglebone上的一个LED闪烁写一个C程序。我知道我可以使用sysfs方式...但是我想看看是否可以得到与/ dev / mem映射物理地址空间相同的结果。
#ifndef _BEAGLEBONE_GPIO_H_
#define _BEAGLEBONE_GPIO_H_
#define GPIO1_START_ADDR 0x4804C000
#define GPIO1_END_ADDR 0x4804DFFF
#define GPIO1_SIZE(GPIO1_END_ADDR - GPIO1_START_ADDR)
#define GPIO_OE 0x134
#define GPIO_SETDATAOUT 0x194
#define GPIO_CLEARDATAOUT 0x190
#define USR0_LED(1 <21)
#define USR1_LED(1 <22)
#define USR2_LED(1< ; 23)
#define USR3_LED(1<< 24)
#endif
然后我有我的C程序,gpiotest.c
#include< stdio.h>
#include< stdlib.h>
#include< sys / mman.h>
#include< sys / stat.h>
#include< fcntl.h>
#includebeaglebone_gpio.h
int main(int argc,char * argv []){
volatile void * gpio_addr = NULL;
volatile unsigned int * gpio_oe_addr = NULL;
volatile unsigned int * gpio_setdataout_addr = NULL;
volatile unsigned int * gpio_cleardataout_addr = NULL;
unsigned int reg;
int fd = open(/ dev / mem,O_RDWR);
printf(映射%X - %X(大小:%X)\\\
,GPIO1_START_ADDR,GPIO1_END_ADDR,GPIO1_SIZE);
gpio_addr = mmap(0,GPIO1_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,fd,GPIO1_START_ADDR);
gpio_oe_addr = gpio_addr + GPIO_OE;
gpio_setdataout_addr = gpio_addr + GPIO_SETDATAOUT;
gpio_cleardataout_addr = gpio_addr + GPIO_CLEARDATAOUT;
if(gpio_addr == MAP_FAILED){
printf(无法映射GPIO \);
exit(1);
}
printf(GPIO映射到%p\\\
,gpio_addr);
printf(GPIO OE映射到%p\\\
,gpio_oe_addr);
printf(GPIO SETDATAOUTADDR映射到%p\\\
,gpio_setdataout_addr);
printf(GPIO CLEARDATAOUT映射到%p\\\
,gpio_cleardataout_addr);
reg = * gpio_oe_addr;
printf(GPIO1 configuration:%X\\\
,reg);
reg = reg& (0xFFFFFFFF - USR1_LED);
* gpio_oe_addr = reg;
printf(GPIO1 configuration:%X\\\
,reg);
printf(开始闪烁LED USR1\\\
);
while(1){
printf(ON\\\
);
* gpio_setdataout_addr = USR1_LED;
sleep(1);
printf(OFF\\\
);
* gpio_cleardataout_addr = USR1_LED;
sleep(1);
}
close(fd);
return 0;
}
输出是:
映射到4804C000 - 4804DFFF(大小:1FFF)
GPIO映射到0x40225000
GPIO OE映射到40225134
GPIO SEDATAOUTADDR映射到0x40225194
GPIO CLEARDATAOUTADDR映射到0x40225190
GPIO1配置:FE1FFFFF
GPIO1配置:FE1FFFFF
开始闪烁LED USR1
ON
OFF
ON
OFF
...
但我看不到LED闪烁。
从程序的输出可以看出,配置正确,FE1FFFFF,
是一致的,因为GPIO1_21,GPIO1_22,GPIO1_23和GPIO1_24被配置为输出
每个人驾驶一个LED。
任何关于原因的想法?
修复是:
pio_addr = mmap(0,GPIO1_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,fd,GPIO1_START_ADDR)
I'm trying to write a C program for blinking a LED on the Beaglebone. I know I can use the sysfs way...but I'd like to see if it is possible to get the same result mapping the physical address space with /dev/mem.
I have a header file, beaglebone_gpio.h wit the following contents:
#ifndef _BEAGLEBONE_GPIO_H_
#define _BEAGLEBONE_GPIO_H_
#define GPIO1_START_ADDR 0x4804C000
#define GPIO1_END_ADDR 0x4804DFFF
#define GPIO1_SIZE (GPIO1_END_ADDR - GPIO1_START_ADDR)
#define GPIO_OE 0x134
#define GPIO_SETDATAOUT 0x194
#define GPIO_CLEARDATAOUT 0x190
#define USR0_LED (1<<21)
#define USR1_LED (1<<22)
#define USR2_LED (1<<23)
#define USR3_LED (1<<24)
#endif
and then I have my C program, gpiotest.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "beaglebone_gpio.h"
int main(int argc, char *argv[]) {
volatile void *gpio_addr = NULL;
volatile unsigned int *gpio_oe_addr = NULL;
volatile unsigned int *gpio_setdataout_addr = NULL;
volatile unsigned int *gpio_cleardataout_addr = NULL;
unsigned int reg;
int fd = open("/dev/mem", O_RDWR);
printf("Mapping %X - %X (size: %X)\n", GPIO1_START_ADDR, GPIO1_END_ADDR, GPIO1_SIZE);
gpio_addr = mmap(0, GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_START_ADDR);
gpio_oe_addr = gpio_addr + GPIO_OE;
gpio_setdataout_addr = gpio_addr + GPIO_SETDATAOUT;
gpio_cleardataout_addr = gpio_addr + GPIO_CLEARDATAOUT;
if(gpio_addr == MAP_FAILED) {
printf("Unable to map GPIO\n");
exit(1);
}
printf("GPIO mapped to %p\n", gpio_addr);
printf("GPIO OE mapped to %p\n", gpio_oe_addr);
printf("GPIO SETDATAOUTADDR mapped to %p\n", gpio_setdataout_addr);
printf("GPIO CLEARDATAOUT mapped to %p\n", gpio_cleardataout_addr);
reg = *gpio_oe_addr;
printf("GPIO1 configuration: %X\n", reg);
reg = reg & (0xFFFFFFFF - USR1_LED);
*gpio_oe_addr = reg;
printf("GPIO1 configuration: %X\n", reg);
printf("Start blinking LED USR1\n");
while(1) {
printf("ON\n");
*gpio_setdataout_addr= USR1_LED;
sleep(1);
printf("OFF\n");
*gpio_cleardataout_addr = USR1_LED;
sleep(1);
}
close(fd);
return 0;
}
The output is:
Mapping 4804C000 - 4804DFFF (size: 1FFF)
GPIO mapped to 0x40225000
GPIO OE mapped to 40225134
GPIO SEDATAOUTADDR mapped to 0x40225194
GPIO CLEARDATAOUTADDR mapped to 0x40225190
GPIO1 configuration: FE1FFFFF
GPIO1 configuratino: FE1FFFFF
Start blinking LED USR1
ON
OFF
ON
OFF
...
but I can't see the led blinking.
As you can see from the output of the program the configuration is correct, FE1FFFFF, is coherent since GPIO1_21, GPIO1_22, GPIO1_23 and GPIO1_24 are configured as outputs, each one driving a LED.
Any idea about the reason?
The fix is:
pio_addr = mmap(0, GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_START_ADDR);
这篇关于通过/ dev / mem驱动Beaglebone GPIO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!