转载地址:http://book.51cto.com/art/201405/438688.htm
如果仅仅针对GPIO硬件构建驱动程序,实现一个字符驱动就可以完成,对用户空间的接口可以是read、write或者自定义的ioctl。内核中却提供了GPIO框架,作为GPIO驱动的统一架构,这样做的好处主要有以下几点:
复用公共代码。
使用sys文件系统作为到用户空间的统一接口,方便操作。
同时提供内核中的API,让内核的其他部分调用。
GPIO驱动的结构如图17-5所示。
GPIO驱动的头文件为:include/linux/gpio.h和include/asm-generic/gpio.h。
GPIO驱动框架的实现代码为:drivers/gpio/gpiolib.c。
GPIO驱动框架不是设备节点,而是sys文件系统,其根目录为:/sys/class/gpio/。
/sys/class/gpio/目录中有一个用于写export的文件,向其中写入一个数字表示建立一个GPIO端口的子目录gpio<N>,例如:
- $ echo 19 > export
如下操作将在/sys/class/gpio/目录中建立一个gpio19子目录,这个子目录中就包含针对19号GPIO的操作。
/sys/class/gpio/gpio<N>目录当中包括了以下文件。
direction:可读写,使用"in"和"out"两个值表示输入和输出。
value:可读写,0代表低电平,1(或其他非0)代表高电平。
edge:表示上升沿和下降沿,可以为"none"、"rising"、"falling"。
/sys/class/gpio/gpiochip<N>/目录描述一个GPIO芯片创建信息,其中包括如下几个文件。
base:表示首个个GPIO从此数字开始。
ngpio:表示GPIO的个数。
label:提供诊断信息。
gpio.h头文件中描述GPIO芯片的结构gpio_chip如下所示:
- struct gpio_chip {
- const char *label; // 该文件的描述信息
- struct device *dev;
- struct module *owner;
- int (*request)(struct gpio_chip *chip, unsigned offset);
- void (*free)(struct gpio_chip *chip, unsigned offset);
- int (*direction_input)(struct gpio_chip *chip, unsigned offset);
- int (*get)(struct gpio_chip *chip, unsigned offset);
- int (*direction_output)(struct gpio_chip *chip,
- unsigned offset, int value);
- int (*set_debounce)(struct gpio_chip *chip,
- unsigned offset, unsigned debounce);
- void (*set)(struct gpio_chip *chip, unsigned offset, int value);
- int (*to_irq)(struct gpio_chip *chip, unsigned offset);
- void (*dbg_show)(struct seq_file *s, struct gpio_chip *chip);
- int base; // 表示首个个GPIO从此数字开始
- u16 ngpio; // 表示GPIO的个数
- const char *const *names; // 表示其名称
- unsigned can_sleep:1;
- unsigned exported:1;
- };