检查 Linux 内核模块中的中断标志

问题描述 投票:0回答:1

我正在尝试检查 Linux 内核模块的中断处理程序中的中断标志(上升标志、下降标志)。
有没有办法通过使用 irq_data 来解决它?
或者是在中断处理程序内读取输入引脚的输入值以检查是否出现下降沿或上升沿的唯一选择?

我的硬件是树莓派 3b+ 我的代码无法区分上升沿和下降沿:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqnr.h>

/* Meta Information */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("");
MODULE_DESCRIPTION("");

/** variable contains pin number o interrupt controller to which GPIO 17 is mapped to */
#define InputPinLine1 17
unsigned int IrqNumberInputLine1;


static irq_handler_t IrqCallbackInputLine1(unsigned int irq, void *dev_id, struct pt_regs *regs) 
{
    struct irq_data *data = irq_get_irq_data(irq);
    uint8_t  trigger_type = irqd_get_trigger_type(data);



    printk("------Line 1 ISR\n");
    printk("trigger:%d\n", trigger_type);


    return (irq_handler_t) IRQ_HANDLED; 
}


static int __init ModuleInit(void) 
{
    printk("Loading module... ");

    // Setup Interrupt for Line 1 
    if(gpio_request(InputPinLine1, "rpi-gpio-17")) 
    {
        printk("Error!\nCan not allocate GPIO InputPinLine1\n");
        return -1;
    }
    if(gpio_direction_input(InputPinLine1)) 
    {
        printk("Error!\nCan not set GPIO 17 to input!\n");
        gpio_free(InputPinLine1);
        return -1;
    }
    IrqNumberInputLine1 = gpio_to_irq(InputPinLine1);
    if(request_irq(IrqNumberInputLine1, (irq_handler_t) IrqCallbackInputLine1, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "IrqCallbackInputLine1", NULL) != 0)
    {
        printk("Error!\nCan not request interrupt nr.: %d\n", IrqNumberInputLine1);
        gpio_free(InputPinLine1);
        return -1;
    }

    return 0;
}


static void __exit ModuleExit(void) 
{
    printk("Unloading module... ");
    free_irq(IrqNumberInputLine1, NULL);
    gpio_free(InputPinLine1);

}


module_init(ModuleInit);
module_exit(ModuleExit);

这只打印值3,发生哪个中断(上升沿、下降沿)并不重要:

static irq_handler_t IrqCallbackInputLine1(unsigned int irq, void *dev_id, struct pt_regs *regs) 
{
    struct irq_data *data = irq_get_irq_data(irq);
    uint8_t  trigger_type = irqd_get_trigger_type(data);



    printk("------Line 1 ISR\n");
    printk("trigger:%d\n", trigger_type);


    return (irq_handler_t) IRQ_HANDLED; 
}

有没有办法通过使用 irq_data 结构来获取中断标志的上升或下降?
如果有人对此有解决方案,那就太酷了。谢谢!

raspberry-pi linux-kernel interrupt gpio
1个回答
0
投票

查看《BCM2837 ARM 外设手册》第 96 页,GPEDSn(GPEDS0 和 GPEDS1)寄存器中的每条 GPIO 线都有一个事件检测状态位。这就是 GPIO 中断控制器用来检查哪些 GPIO 中断处于待处理状态的方法。它是一个位,因此如果同一 GPIO 线启用了多种类型的事件,则无法判断发生了哪种类型的事件。 您必须在中断处理程序中检查 GPIO 线的电平,并希望没有错过任何转换。

© www.soinside.com 2019 - 2024. All rights reserved.