linux gpio模拟内存,linux内核中GPIO的使用(一)--IO内存

一、相关概念

使用IO内存将物理地址映射为虚拟地址,再通过对虚拟地址的操作来控制硬件。所谓的IO内存是指一种编址方式,不同cpu平台使用的编址方式不同,一种是“IO内存”方式,也叫统一编址方式,是指内存和外设的地址是在同一个地址空间上的,如:ARM、powerpc 、MIPS等平台;另一种是“IO端口”方式,也叫独立编址方式,是指内存的地址空间和外设的地址空间是分开的,如x86平台。在嵌入式系统中,可以通过查看两个文件中的内容来确认是哪一种编址方式:/proc/iomem 和/proc/ioports,哪一个文件有内容就表示该平台使用哪一种编址方式。

二、程序设计思路

驱动安装—>申请IO内存资源—>物理地址的映射—>得到虚拟地址—>访问虚拟地址—>控制外设硬件

驱动卸载—>解除地址映射—>释放IO内存资源

用到的函数有:

request_mem_region()、ioremap()、release_mem_region()、iounmap()

三、程序设计与分析

1)申请IO内存资源

struct resource * request_mem_region( resource_size_t start, resource_size_t n, const char *name)

参数分析:

resource_size_t start:IO内存的开始地址,该地址是物理地址;

resource_size_t n:要申请的IO内存资源的大小,单位为字节;

const char *name:给所申请的IP内存资源取一个名字;

返回值:

申请成功,返回一个struct resource类型的指针;

申请失败,返回NULL;

2)释放IO内存资源

void release_mem_region(resource_size_t start, resource_size_t n) 参数分析: resource_size_t start:IO内存的开始地址,该地址是物理地址; resource_size_t n:要申请的IO内存资源的大小,单位为字节;

3)IO内存映射(物理地址—>虚拟地址)

void __iomem *ioremap(phys_addr_t offset, unsigned long size)

参数分析:

phys_addr_t offset:准备映射的物理地址空间的开始地址

unsigned long size:要映射的物理地址空间的大小,单位为字节

返回值:

映射成功,返回一个虚拟地址

映射失败,返回NULL;

4)IO内存映射的解除

void iounmap(volatile void __iomem *addr);

参数分析:

volatile void __iomem *addr:前面映射得到的虚拟地址

四、简单的实例

简单的LED驱动,实现对基于S5PV210平台的LED灯控制,所用寄存器:GPJ2CON(0xe0200280)、GPJ2DAT(0xe0200284),主要代码如下:

static int * GPJ2CON_VA; /*定义全局变量*/

static int * GPJ2DAT_VA;

static struct resource * gpio_led_source;

.....

在驱动的初始化函数static int __init leddev_init(void)中添加相关代码:

gpio_led_source = request_mem_region(0xe0200280, 8, “GPIO_LED”);

if(gpio_led_source == NULL)

{

printk("led_request_mem_region error!\n");

goto err_led_request_mem_region; /*出错处理*/

}

GPJ2CON_VA = ioremap(0xe0200280, 8);

if(GPJ2CON_VA == NULL)

{

printk("led ioremap error!\n");

goto err_led_ioremap; /*出错处理*/

}

GPJ2DAT_VA = GPJ2CON_VA + 1; /* GPJ2CON和GPJ2DAT的地址刚好相邻*/

*GPJ2CON_VA &= ~0xffff; /*initial led GPIO*/

*GPJ2CON_VA |= 0x1111;

*GPJ2DAT_VA |= 0xf;

printk("GPIO initial success!\n");

在驱动的退出函数static int __exit leddev_exit(void)中:

iounmap(GPJ2CON_VA); /*解除IO映射*/

release_mem_region(0xe0200280, 8); /*释放IO内存资源*/

unregister_chrdev_region(MKDEV(leddev_Major, leddev_Minor), 1); /*注销设备号*/

cdev_del(&ledodev); /*从内核中删除设备 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值