ARM体系芯片 IO口实际上是4G内存空间中的一部分地址空间,所以,本质上就是操作内存,它和其他的片上外设没有区别。这类 IO 称为 IO内存。在芯片还有一类称IO端口,这一类要配置就不是通过ioremp这种方式。这种形态IO,一般出现在X86芯片 。实际应用中,IO内存操作可以使用ioremap映射再使用指针操作对应的寄存器,但是比较少使用,一般 使用内核提供GPIO操作函数。
内核提供的通用GPIO操作的API接口文件 :Gpio.h (include\linux)
int gpio_get_value(unsigned int gpio)
功能:获取IO口的状态
参数:gpio 要获取的IO口编号
返回:IO口状态
void gpio_set_value(unsigned int gpio, int value)
功能:设置IO口的状态
参数:gpio 要获取的IO口编号 ,value:要设置的值 ,0或1
返回:无
int gpio_cansleep(unsigned int gpio) 比较少用。
功能:判断IO是否具可以休眠
参数:gpio 要获取的IO口编号
返回:非0,可以休眠
int gpio_to_irq(unsigned int gpio) 很常用
功能:通过Io口编号转换成对应 的外部中断编号
参数:gpio 要获取的IO口编号
返回:成功:中断编号
失败: - ENXIO #define ENXIO 6 /* No such device or address */
在gpiolib.c 还实现其他的gpio操作函数
int gpio_direction_output(unsigned gpio, int value)
功能:指定IO口gpio设置为输出功能,并且输出指出电平value
int gpio_direction_input(unsigned gpio)
功能:读取指定IO口gpio电平状态
int gpio_request(unsigned gpio, const char *label) 这个函数可用不可不用,建议使用。
功能:向内核申请指定IO,所申请的IO口会被内核记录。
参数:gpio 申请IO口编号 ,label:申请者的名字,随便。
已经被申请的IO,在没有释放前再次申请将会失败。
返回:成功:0;失败:负数
使用IO时候可以申请,也可以不申请 ,建议申请,这样对IO是来说是一种保护。
示例:
a驱动 和b驱动使用相同的IO, a配置为输入,b配置为输出。
如果两个驱动使用IO口都不申请,都可以成功安装,这样共用的IO功能上冲突。但是另外驱动并不知道,这样导致内核存在BUG,
想实现安全使用,必须要求所用使用IO的驱动程序使用申请再使用,如果哪个驱动没有申请,其他的申请,则没有申请的驱动会绕过内核检测,直接使用,这样达不到保护效果了。
void gpio_free(unsigned gpio) //此函数和 gpio_request配对使用,功能相反,
功能:释放向内核已经申请的指定IO。 所释放的IO口会在内核记录消除。
释放的io,可以再次被申请。
芯片厂家一般会提供一个芯片级io配置的代码(drivers\gpio)
三星公司提供的函数:
Gpio-samsung.c (drivers\gpio)
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
功能:把指定IO口配置为指定功能
pin:管脚编号,和前面的函数相同的定义方式
config:
功能对应的数值,这个需要查看具体芯片手册对应的IO功能配置说明。
如:EXYNOS4412 芯片, 0x0 是输入,0x1输出,其他 复用功能(具体功能看手册)
int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, unsigned int cfg)
功能:把指定范围IO口配置为指定功能
start:管脚编号,和前面的函数相同的定义方式
nr: 连续io数量
cfg:
功能对应的数值,这个需要查看具体芯片手册对应的IO功能配置说明。
如:EXYNOS4412 芯片, 0x0 是输入,0x1输出,其他 复用功能(具体功能看手册)
其实这个函数内部实现就多次调用 s3c_gpio_cfgpin
unsigned s3c_gpio_getcfg(unsigned int pin)
功能:获取指定IO的功能对应的配置值(查询IO功能)
pin:管脚编号,和前面的函数相同的定义方式
返回 :功能值
要使用上面函数,还需要解决函数的 参数 gpio 的意义。
1)不是看芯片手册 上芯片管脚编号
2)使用编号是由Linux源码中头文件所定义的编号。
a.不同芯片,IO编号,功能都不一样,这个定义头文件一般在存放和具体芯片类型相关的文件夹中。
arch/构架/mach-芯片型号/include/mach/gpio.h
如EXYNOS4412芯片:
arch/arm/mach-exynos/include/mach/gpio.h
以下是部分定义:使用方法 宏名(组内管脚编号),如 tiny4412开发板上4个LED是在GPM4的0~3上,所以它定义:
EXYNOS4X12_GPM4(0)
EXYNOS4X12_GPM4(1)
EXYNOS4X12_GPM4(2)
EXYNOS4X12_GPM4(3)