标志
| 功能 |
IRQF_SHARED |
多个设备共享一个中断线,共享的所有中断都必须指
定此标志。如果使用共享中断的话,
request_irq 函数的
dev
参数就是唯一区分他们的标志。
|
IRQF_ONESHOT
| 单次中断,中断执行一次就结束。 |
IRQF_TRIGGER_NONE | 无触发。 |
IRQF_TRIGGER_RISING | 上升沿触发。 |
IRQF_TRIGGER_FALLING | 下降沿触发。 |
IRQF_TRIGGER_HIGH | 高电平触发。 |
IRQF_TRIGGER_LOW | 低电平触发。 |
- 1 gpio5 : gpio @020ac000{
- 2 compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
- 3 reg = <0x020ac000 0x4000>;
- 4 interrupts =
74 IRQ_TYPE_LEVEL_HIGH>, 75 IRQ_TYPE_LEVEL_HIGH>; - 5 gpio-controller;
- 6 #gpio-cells = <2>;
- 7 interrupt-controller;
- 8 #interrupt-cells = <2>;
- 9 };
第 4 行,interrupts 描述中断源信息,对于 gpio5 来说一共有两条信息,中断类型都是 SPI,触发电平都是 IRQ_TYPE_LEVEL_HIGH。不同之处在于中断源,一个是 74,一个是 75。
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- //定义结构体表示我们的节点
- struct device_node *test_device_node;
- struct property *test_node_property;
- //要申请的中断号
- int irq;
- // GPIO 编号
- int gpio_nu;
- /*** @description: 中断处理函数 test_key
- * @param {int} irq :要申请的中断号
- * @param {void} *args :
- * @return {*}IRQ_HANDLED
- */
- irqreturn_t test_key(int irq, void *args)
- {
- printk("test_key \n");
- return IRQ_RETVAL(IRQ_HANDLED);
- }
- /******************************************************************************
- * @brief beep_probe : 与设备信息层(设备树)匹配成功后自动执行此函数,
- * @param inode : 文件索引
- * @param file : 文件
- * @return 成功返回 0
- ******************************************************************************/
- int beep_probe(struct platform_device *pdev)
- {
- int ret = 0;
- // 打印匹配成功进入 probe 函数
- printk("beep_probe\n");
- // of_find_node_by_path 函数通过路径查找节点,/test_key 是设备树下的节点路径
- test_device_node = of_find_node_by_path("/test_key");
- if (test_device_node == NULL)
- {
- //查找节点失败则打印信息
- printk("of_find_node_by_path is error \n");
- return -1;
- }
- //of_get_named_gpio 函数获取 GPIO 编号
- gpio_nu = of_get_named_gpio(test_device_node, "gpios", 0);
- if (gpio_nu < 0)
- {
- printk("of_get_namd_gpio is error \n");
- return -1;
- }
- //设置 GPIO 为输入模式
- gpio_direction_input(gpio_nu);
- //获取 GPIO 对应的中断号
- // irq = gpio_to_irq(gpio_nu);
- irq =irq_of_parse_and_map(test_device_node,0);
- printk("irq is %d \n", irq);
- /*申请中断,irq:中断号名字
- test_key:中断处理函数
- IRQF_TRIGGER_RISING:中断标志,意为上升沿触发
- "test_key":中断的名字
- */
- ret = request_irq(irq, test_key, IRQF_TRIGGER_RISING, "test_key", NULL);
- if (ret < 0)
- {
- printk("request_irq is error \n");
- return -1;
- }
- return 0;
- }
- int beep_remove(struct platform_device *pdev)
- {
- printk("beep_remove\n");
- return 0;
- }
- const struct platform_device_id beep_idtable = {
- .name = "keys",
- };
- const struct of_device_id of_match_table_test[] = {
- {.compatible = "keys"},
- {},
- };
- struct platform_driver beep_driver = {
- //3. 在 beep_driver 结构体中完成了 beep_probe 和 beep_remove
- .probe = beep_probe,
- .remove = beep_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "beep_test",
- .of_match_table = of_match_table_test},
- //4 .id_table 的优先级要比 driver.name 的优先级要高,优先与.id_table 进行匹配
- .id_table = &beep_idtable};
- /**
- * @description: 模块初始化函数
- * @param {*}
- * @return {*}
- */
- static int beep_driver_init(void)
- {
- //1.我们看驱动文件要从 init 函数开始看
- int ret = 0;
- //2.在 init 函数里面注册了 platform_driver
- ret = platform_driver_register(&beep_driver);
- if (ret < 0)
- {
- printk("platform_driver_register error \n");
- }
- printk("platform_driver_register ok \n");
- return 0;
- }
- /**
- * @description: 模块卸载函数
- * @param {*}
- * @return {*}
- */
- static void beep_driver_exit(void)
- {
- free_irq(irq, NULL);
- platform_driver_unregister(&beep_driver);
- printk("gooodbye! \n");
- }
- module_init(beep_driver_init);
- module_exit(beep_driver_exit);
- MODULE_LICENSE("GPL");