从硬件 IRQ 号获取 Linux IRQ 号
Getting Linux IRQ number from hardware IRQ number
我有一个 GPIO 外围设备,在设备树中定义为:
gpio0: gpio@2300000
{
compatible = "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
我想为此编写一个中断处理程序(作为内核模块)。但是这个 IRQ 号 (66) 是硬件的,我需要一个虚拟的 Linux IRQ 号来将它传递给 request_irq
.
如何得到这个数字?只有一个中断控制器(GIC)。
有没有一种方法可以在不编写平台设备驱动程序的情况下做到这一点(因为系统中可能已经有一个在工作,我想我不能注册另一个)。
根据您的评论,您希望将 GPIO 注册为中断。
您发布的设备树节点是中断控制器节点,我们手头的任务不会关注它。
要将 gpio 注册为中断,您首先需要找到一个可以配置为中断的 GPIO(在大多数现代处理器中,所有 GPIO 都支持它)然后您必须确保它不被某些人使用通过多路复用其他设备(如果它被 SPI 或 UART 等设备使用,如果您不使用该实体,则可以从设备树中禁用它们)。
现在您有了可以使用的 GPIO 引脚。在内核上找到该引脚对应的 GPIO 编号(这取决于您的处理器及其载板的架构)。
当你拥有它时,你可以编写一个简单的模块来导出你的 GPIO 并将其用作中断。
下面是来自 http://derekmolloy.ie
的片段
gpio_request(gpioButton, "sysfs"); // Set up the gpioButton
gpio_direction_input(gpioButton); // Set the button GPIO to be an input
gpio_set_debounce(gpioButton, 200); // Debounce the button with a delay of 200ms
gpio_export(gpioButton, false); // Causes gpio115 to appear in /sys/class/gpio
// the bool argument prevents the direction from being changed
// Perform a quick test to see that the button is working as expected on LKM load
printk(KERN_INFO "GPIO_TEST: The button state is currently: %d\n", gpio_get_value(gpioButton));
// GPIO numbers and IRQ numbers are not the same! This function performs the mapping for us
irqNumber = gpio_to_irq(gpioButton);
printk(KERN_INFO "GPIO_TEST: The button is mapped to IRQ: %d\n", irqNumber);
// This next call requests an interrupt line
result = request_irq(irqNumber, // The interrupt number requested
(irq_handler_t) ebbgpio_irq_handler, // The pointer to the handler function below
IRQF_TRIGGER_RISING, // Interrupt on rising edge (button press, not release)
"ebb_gpio_handler", // Used in /proc/interrupts to identify the owner
NULL); // The *dev_id for shared interrupt lines, NULL is okay
Link 到完整代码。
我有一个 GPIO 外围设备,在设备树中定义为:
gpio0: gpio@2300000
{
compatible = "fsl,qoriq-gpio";
reg = <0x0 0x2300000 0x0 0x10000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
我想为此编写一个中断处理程序(作为内核模块)。但是这个 IRQ 号 (66) 是硬件的,我需要一个虚拟的 Linux IRQ 号来将它传递给 request_irq
.
如何得到这个数字?只有一个中断控制器(GIC)。
有没有一种方法可以在不编写平台设备驱动程序的情况下做到这一点(因为系统中可能已经有一个在工作,我想我不能注册另一个)。
根据您的评论,您希望将 GPIO 注册为中断。 您发布的设备树节点是中断控制器节点,我们手头的任务不会关注它。
要将 gpio 注册为中断,您首先需要找到一个可以配置为中断的 GPIO(在大多数现代处理器中,所有 GPIO 都支持它)然后您必须确保它不被某些人使用通过多路复用其他设备(如果它被 SPI 或 UART 等设备使用,如果您不使用该实体,则可以从设备树中禁用它们)。
现在您有了可以使用的 GPIO 引脚。在内核上找到该引脚对应的 GPIO 编号(这取决于您的处理器及其载板的架构)。
当你拥有它时,你可以编写一个简单的模块来导出你的 GPIO 并将其用作中断。
下面是来自 http://derekmolloy.ie
的片段gpio_request(gpioButton, "sysfs"); // Set up the gpioButton
gpio_direction_input(gpioButton); // Set the button GPIO to be an input
gpio_set_debounce(gpioButton, 200); // Debounce the button with a delay of 200ms
gpio_export(gpioButton, false); // Causes gpio115 to appear in /sys/class/gpio
// the bool argument prevents the direction from being changed
// Perform a quick test to see that the button is working as expected on LKM load
printk(KERN_INFO "GPIO_TEST: The button state is currently: %d\n", gpio_get_value(gpioButton));
// GPIO numbers and IRQ numbers are not the same! This function performs the mapping for us
irqNumber = gpio_to_irq(gpioButton);
printk(KERN_INFO "GPIO_TEST: The button is mapped to IRQ: %d\n", irqNumber);
// This next call requests an interrupt line
result = request_irq(irqNumber, // The interrupt number requested
(irq_handler_t) ebbgpio_irq_handler, // The pointer to the handler function below
IRQF_TRIGGER_RISING, // Interrupt on rising edge (button press, not release)
"ebb_gpio_handler", // Used in /proc/interrupts to identify the owner
NULL); // The *dev_id for shared interrupt lines, NULL is okay
Link 到完整代码。