linux下使用mmap控制GPIO

本文介绍如何在Linux环境下通过mmap内存映射的方式控制GPIO接口,实现LED显示,并提供了完整的源代码示例。

linux下使用mmap控制GPIO

原文地址:  http://mikenoodle.blog.163.com/blog/static/1133352200861274159875/

 

如果没有/dev/mem,则执行

mknod /dev/mem c 1 1

编译下面的代码

 

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include<sys/mman.h> 
#include<fcntl.h> 
#include <asm/page.h>


#define GPIO_CTL_BASE 0x56000000 
#define rGPBCON 0x10 
#define rGPBDAT 0x14 
#define rGPBUP 0x18

unsigned int *GPBCON,*GPBDAT,*GPBUP;

void Led_Display(int data)
{
*(volatile unsigned int *)GPBDAT= (~data & 0xf)<<7;//因为是第7-10位,且只有4位,故 左移7 
}

int main(int argc, char** argv) 
{ 
int gpio_fd, ip=0, i=0; 
unsigned char *gpio_map; 


gpio_map = NULL; 
GPBCON = NULL; 
GPBDAT = NULL; 
GPBUP = NULL;

gpio_fd =open("/dev/mem",O_RDWR); 
if (gpio_fd == -1) 
{ 
printf("can't open /dev/mem.\n"); 
return ; 
}

gpio_map = (unsigned char *)mmap(0, 0xbc,PROT_READ | PROT_WRITE, MAP_SHARED,gpio_fd, GPIO_CTL_BASE); 
GPBCON = (volatile unsigned int *) (gpio_map+rGPBCON); 
GPBDAT = (volatile unsigned int *) (gpio_map+rGPBDAT); 
GPBUP = (volatile unsigned int *) (gpio_map+rGPBUP);

//初始化io
*(volatile unsigned int *)GPBCON=0x154000;
*(volatile unsigned int *)GPBUP=0x7ff;

for(i=0;i<16;i++)
{
Led_Display(i);
sleep(1);
}

munmap(0, 0xbc);
if (gpio_fd != 0x0) 
{ 
close(gpio_fd); 
}

printf("GPIO Control Test end\n"); 

}

### 如何在Linux使用GPIO通过`mmap`进行内存映射 为了实现对GPIO的操作,可以通过访问已映射到进程地址空间的物理内存来完成。这通常涉及到利用`/dev/mem`设备文件以及调用`mmap()`函数将特定硬件寄存器所在的物理地址区域映射至用户程序可直接读写的虚拟地址区间。 #### 打开/dev/mem并获取文件描述符 首先需要打开特殊文件`/dev/mem`以获得一个指向该资源的句柄,在此之后可以执行实际的映射操作: ```c #include <fcntl.h> int fd; if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { perror("Unable to open /dev/mem"); } ``` #### 映射指定范围内的物理地址到当前进程中 接下来就是核心部分—-使用`mmap()`来进行内存映射。这里假设已经知道了目标外设(比如某个具体的GPIO控制器)所处的确切基址及其大小;对于ARM架构而言,这些信息往往可以在对应的板级支持包文档里找到。 ```c #define BCM2708_PERI_BASE 0x3F000000 // RPi上的BCM2835 SoC周边基础地址 #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) volatile unsigned *gpio_map; // 进行映射... gpio_map = (unsigned *)mmap( NULL, BLOCK_SIZE, /* 需要映射多大一块 */ PROT_READ|PROT_WRITE, /* 权限设置 */ MAP_SHARED, /* 共享模式 */ fd, /* 文件描述符 */ GPIO_BASE /* 物理起始位置 */ ); ``` 一旦成功完成了上述过程,则可以直接通过对返回指针`gpio_map`所指向的位置进行位运算等方式控制相应的引脚状态了[^4]。 需要注意的是,由于这种做法绕过了标准库所提供的API接口而直接作用于底层硬件层面,因此存在一定的风险性和平台依赖特性。此外,出于安全考虑,现代发行版可能默认禁用了对`/dev/mem`的未授权访问权限,所以在尝试之前最好先查阅相关资料确认环境配置情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值