Linux中编写GPIO驱动


前言

GPIO是嵌入式开发中常用的一个模块,Linux下的任何外设驱动,最终目的都是要配置相应的硬件寄存器。在Linux中,不管是内核空间代码,还是用户空间代码,访问的都是虚拟地址。
gpio子系统是Linux内核中用于管理GPIO资源的一套系统,提供了很多GPIO相关的API接口,虽然方便驱动开发者使用,但最终还是得操作寄存器;在使用此系统前,需要向内核注册这一套操作的方法。
pinctrl子系统通常用于管理SoC中各PIN脚的复用功能和电气特性。对于 ZYNQ MPSoC 来说,使用了 vivado 图形化完成了对 PIN 的配置并在 fsbl 阶段将
配置信息写入了硬件寄存器中,所以不需要在内核阶段进行配置。


一、MMU是什么?

开始前我们要了解什么是MMU。Linux中一个重要的部分就是MMU(内存管理单元),其作用是将虚拟空间映射到物理空间,让我们可以方便的操作各个硬件。像一般32位的系统,虚拟地址范围即为2^32=4GB。这样我们就可以通过程序中的虚拟地址对硬件进行操作。

二、操作GPIO

内核中操作GPIO有两种方法,一种是比较硬核的不使用linux为我们提供的标准GPIO接口,还有一种就是用标准接口,下面来说明这两种方式。

1.不使用GPIO标准接口

既然不用标准接口,我们就只能通过看数据手册,查找对应寄存器的地址和各bit对应功能,映射地址的方式操作对应的物理设备,主要用到的接口有:

将一个IO地址空间映射到内核的虚拟地址空间
#define ioremap(phys_addr,size) __arm_ioremap((phys_addr), (size), MT_DEVICE)
void __iomem *__ioremap(unsigned long phys_addr, size_t size, unsigned long flags);
phys_addr:物理起始地址
size:映射内存空间大小
返回虚拟地址首地址

释放映射:
void iounmap (volatile void __iomem *addr);
addr:虚拟地址首地址

读操作:
u8 readb(const volatile void __iomem *addr);	8bit
u16 readw(const volatile void __iomem *addr);	16bit
u32 readl(const volatile void __iomem *addr);	32bit

写操作:
void writeb(u8 value, volatile void __iomem *addr);
void writew(u16 value, volatile void __iomem *addr);
void writel(u32 value, volatile void __iomem *addr);

例子:
假设有个GPIO口控制LED灯的开关,寄存器地址为0x3000001C,第12bit为0时gpio拉低,1时拉高。
#define GPIO_LED_REG ((unsigned int)0x3000001C)

unsigned int *addr = (unsigned int *)ioremap(GPIO_LED_REG,4);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值