GPIO中断使用小结

来源:互联网 发布:顺丰科技 知乎 编辑:程序博客网 时间:2024/06/05 20:44

GPIO 中断使用小结

最近在开发一个跟GPIO中断相关的功能,发现还是有很多函数比较有意思,现在总结一下:

1. 调用gpio_is_valid(int gpio_num)判断该GPIO是否有效

2. 调用gpio_request(unsigned gpio, const char *label)申请使用gpio,其中参数label为字符串,用于标志此GPIO,申请成功后,可以通过/sys/kernel/debug/gpio文件查看到该GPIO的状态

3. 调用gpio_direction_input(unsigned gpio)设置该GPIO为输入

4. 调用函数根据GPIO号申请中断:request_threaded_irq(unsigned int irq, irq_handler_t handler,irq_handler_t thread_fn, unsigned long irqflags,const char *devname, void *dev_id)

其中irq为系统分配的中断号,可以用gpio_to_irq(unsigned gpio)获取。

handler中断处理函数,即为中断的上半部,一般设为NULL。

thread_fn为中断处理下半部,中断发生后,系统会创建一个线程来响应中断,线程会调用thread_fn函数,一般在这个函数里完成中断事件的响应。

irqflags为中断判断条件,取值有IRQF_TRIGGER_HIGH、IRQF_TRIGGER_LOW、IRQF_TRIGGER_RISING、IRQF_TRIGGER_FALLING、IRQF_ONESHOT等一种或几种组合,注意如果handler为NULL时,必须加上IRQF_ONESHOT,表示在中断线程中关闭该中断,否则申请中断会失败。

devname,为中断名称,在/proc/interrupts下可以看到

dev_id是一个指针,一般指向设备相关的结构体,在中断发生后,这个指针会被传递到thread_fn,在那里对结构体里的数据做操作。

5. 中断发生后,系统会调用thread_fn(int irq, void *data),其中irq为中断号,data指针由dev_id传递进来,通过这个指针完成对设备结构体数据的操作。

例如:

 

int cradle_detect_gpio = -1;

static irqreturn_t cradle_detect_irq(int irq, void *data)

{

int ret = IRQ_HANDLED;

pr_info("detect cradle irq %d gpio value %d\n", irq, __gpio_get_value(cradle_detect_gpio));

/* To be done */

return ret;

}

static int setup_cradle_detect(struct device_node *np,

struct data *data)

{

int ret = 0;

/*根据dtsi文件查找名为cradle-detect的gpio号*/

cradle_detect_gpio = of_get_named_gpio(np, "cradle-detect", 0);

pr_info("cradle_detect_gpio %d\n", cradle_detect_gpio);

if (gpio_is_valid(cradle_detect_gpio)) {  //判断gpio是否有效

ret = gpio_request(cradle_detect_gpio, "cradle_detect_gpio");

if (ret) {

pr_err("%s: gpio_request failed for cradle_detect_gpio.\n", __func__);

return -EINVAL;

}

gpio_direction_input(cradle_detect_gpio);  //设置为输入

ret = request_threaded_irq(gpio_to_irq(cradle_detect_gpio), NULL, cradle_detect_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "cradle_detect", data);   //申请中断

pr_info("request_threaded_irq %d\n", ret);

if (ret) {

return ret;

}

pr_info("request_threaded_irq success\n");

}

return 0;

}

 

xxx_init()

{

...

setup_cradle_detect(struct device_node *np,

struct data *data);   //初始化中断

...

}


在申请中断成功后,可以通过命令查看名为cradle_detect的中断:

cat /proc/interrupts|grep cradle

493: 18 0 0 0  msm_tlmm_irq  cradle_detect

另外也可以查看cradle_detect_gpio的状态

cat /sys/kernel/debug/gpio|grep cradle

 gpio-1009 (cradle_detect_gpio  ) in  hi

如果cradle_detect_gpio状态有改变时,是会有中断产生并进入中断处理函数的:

<6>[ 5099.125151] detect cradle irq 493 gpio value 0

<6>[ 5100.171453] detect cradle irq 493 gpio value 1


1 0
原创粉丝点击