GPIO子系统框架图解
gpio子系统帮助我们管理整个系统gpio的使用情况,同时通过sys文件系统导出了调试信息和应用层控制接口。它内部实现主要提供了两类接口,一类给bsp工程师,用于注册gpio chip(也就是所谓的gpio控制器驱动),另一部分给驱动工程师使用,为驱动工程师屏蔽了不同gpio chip之间的区别,驱动工程师调用的api的最终操作流程会导向gpio对应的gpio chip的控制代码,也就是bsp的代码。
1.linux子系统框架
在Linux中,GPIO子系统大致分为3层:
GPIO硬件
GPIO硬件驱动层
抽象驱动框架
从上到下为:
2.结构体抽象
1、GPIO描述符gpio_desc
在Linux 中,GPIo驱动框架是在gpiolib.c中实现的。对于每一个GPIo引脚,抽象了一个描述符gpio_desc :
目录: kernel-4.4\drivers \gpiolgpiolib.h
struct gpio_desc {
struct gpio_device *gdev;
unsigned long flags;
/* flag symbols are bit numbers */
#define FLAG_REQUESTED 0
#define FLAG_IS_OUT 1
#define FLAG_EXPORT 2 /* protected by sysfs_lock */
#define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */
#define FLAG_ACTIVE_LOW 6 /* value has active low */
#define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */
#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
#define FLAG_IS_HOGGED 11 /* GPIO is hogged */
#define FLAG_SLEEP_MAY_LOOSE_VALUE 12 /* GPIO may loose value in sleep */
/* Connection label */
const char *label;
/* Name of the GPIO */
const char *name;
};
2、GPIO操作集抽象:gpio_chip
GPIo硬件是由若干个 GPIO Controller组成,每一个Controller负责管理一组GPIo引脚。结构体gpio_chip表示一组GPIO引脚的控制器,其中定义了对于具体硬件驱动的下层接口:
目录: kernel-4.4/include/linux/gpio/driver.h
struct gpio_chip {
const char *label; //标号为了给系统提供诊断保留用的
struct gpio_device *gpiodev; //提供给 GPIO 可选择的设备
struct device *parent;
struct module *owner; //标定拥有者防止被移除的模块污染正在使用的 GPIO
int (*request)(struct gpio_chip *chip, //请求 GPIO
unsigned offset);
......
}
其中抽象了所有GPIo 的硬件特性,为上层用户(内核开发者所编写的驱动程序)提供统一的驱动接口。框架中主要功能分为三部分:
GPIO 参数的设置,包括配置引脚为输入或输出,设置引脚上的电平高低等;
GPIO引脚状态查询,即查询GPIO引脚上当前的电平状态;
中断管理,中断的使能与关闭,中断方式的选择,中断号管理等。
gpio_chip 中驱动接口如下:
具体硬件驱动需要根据不同硬件平台的特性实现上述接口,在系统初始化时,将每个gpio_chip注册进驱动框架,在驱动框架中会维护一个GPIo描述符数组,用于存储注册进来的 GPIo引脚的具体硬件驱动。
通过ANBA总线连接进cPu的 GPIo控