做个STM32开发的都知道,通过程序配置让普通的GPIO口具有中断功能。这样对于设备检测某些硬件的自动设备要方便的多。那么在嵌入式的Linux是否具有这样的功能呢?答案是肯定的,下面我们就来介绍一下如何配置嵌入式Linux的GPIO中断。
1.内核中配置GPIO中断
Linux内核的输入子系统是对分散的、多种不同类别的输入设备(如键盘、鼠标、跟踪球、操作杆、触摸屏、加速计和手写板)进行统一处理的驱动程序。输入子系统带来的好处:
a.统一了物理形态各异的相似的输入设备的处理功能。例如,各种鼠标,不论是PS/2、USB,还是蓝牙,都做同样的处理;
b.提供了用于分发输入报告给用户应用程序的简单的事件接口;
c.抽取出了输入驱动程序的通用部分,简化了驱动程序,并引入了一致性;
在内核中,按键的驱动已经完成!!!不需要我们自己写。driver/input/keyboard/gpio_keys.c 就是驱动文件。关于源码大家请下载Linux内核源码进行查看,下面介绍几个重点函数的实现。
1.1 gpio_keys_probe 函数
gpio_keys_probe函数在gpio_keys.c文件中,源码如下:
static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct gpio_keys_drvdata *ddata;
struct device *dev = &pdev->dev;
struct gpio_keys_platform_data alt_pdata;
struct input_dev *input;
int i, error;
int wakeup = 0;
if (!pdata) {
error = gpio_keys_get_devtree_pdata(dev, &alt_pdata);
if (error)
return error;
pdata = &alt_pdata;
}
/*kzalloc 对kmalloc的封装,会清0分配的空间*/
ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
pdata->nbuttons * sizeof(struct gpio_button_data),
GFP_KERNEL);
/*分配一个input设备*/
input = input_allocate_device();
if (!ddata || !input) {
dev_err(dev, "failed to allocate state\n");
error = -ENOMEM;
goto fail1;
}
ddata->input = input;
ddata->n_buttons = pdata->nbuttons;
ddata->enable = pdata->enable;
ddata->disable = pdata->disable;
mutex_init(&ddata->disable_lock);
/* 设置input设备属性 */
platform_set_drvdata(pdev, ddata);
input_set_drvdata(input, ddata);
input->name = pdata->name ? : pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
input->open = gpio_keys_open;
input->close = gpio_keys_close;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
/* 使能系统的自动清除中断标志位功能 */
if (pdata->rep)
__set_bit(EV_REP, in