先上一个代码实例:
static int gpio_irq_init(void) { int ret; ret = gpio_request (AT91_PIN_PC6, "IRQ"); /* GPIO request*/ if (ret) { printk ("Unable to request PC6\n"); } at91_set_GPIO_periph (AT91_PIN_PC6, 1); // Pull Up at91_set_gpio_input (AT91_PIN_PC6, 1); // input with Pull Up at91_set_deglitch (AT91_PIN_PC6, 1); // deglitch ret = request_irq (AT91_PIN_PC6,my_irq_handler_func,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING , "MyIRQ", NULL); if (ret) { printk ("IRQ %d is not free\n", AT91_PIN_PC6); return ret; } return 0; }
上面的例子,将PC6设置成GPIO,输入,上拉电阻使能,申请了上升沿或者下降沿触发中断。上面的例子在AT91sam9260上测试通过,上升沿和下降沿都可以触发中断。
简单介绍一下其中的内容,一般gpio_request封装了mem_request(),起保护作用,最后要调用mem_free之类的。主要是告诉内核这地址被占用了。当其它地方调用同一
地址的gpio_request就会报告错误,该地址已被申请。在/proc/mem应该会有地址占用表描述。
这种用法的保护作用前提是大家都遵守先申请再访问,有一个地方没遵守这个规则,这功能就失效了。好比进程互斥,必需大家在访问临界资源的时候都得先获取锁一样,其中
一个没遵守约定,代码就废了。
另外关于at91sam926x的GPIO的中断触发类型,在linux 2.6内核的arch/arm/mach-at91中的gpio.c文件中,有一个函数如下:
static int gpio_irq_type(unsigned pin, unsigned type) { switch (type) { case IRQ_TYPE_NONE: case IRQ_TYPE_EDGE_BOTH: return 0; default: return -EINVAL; } }
电平触发也不支持。
另外需要注意GPIO口的上拉电阻,不同的板子可能情况不一样,更加自己的情况决定上拉电阻是否使能。
转载请注明:http://blog.csdn.net/shanzhizi/article/category/1277259