Es wird ein Interrupt alle 10ms auf GPIO_39 in pandaboard OMAP4 generiert. Ich habe einen Handler dafür im Linux-Treibercode registriert, aber der Handler wird nicht aufgerufen, da der Interrupt nicht erkannt wird.Wie erkennt man Interrupt auf einer GPIO-Leitung in Embedded Linux?
Ich habe auf der Hardware-Ebene (durch Sondierung der GPIO-Pin) sichergestellt, dass der Interrupt tatsächlich generiert wird. Es ist nur, dass die Software es nicht erkennen kann.
Ich habe folgendes in meinem Treibercode.
#define GPIO_NO 39
iowrite16(0x3, gpio_39_address + 2); /* Configured the pin 22 to be used as gpio. */
ret = gpio_request(GPIO_NO, "Claiming GPIO");
if(ret < 0)
{
printk(KERN_ALERT "%s: Claiming GPIO_%d failed\n", __func__, GPIO_NO);
return -1;
}
else
{
printk(KERN_INFO "%s: Claiming GPIO_%d successful\n", __func__, GPIO_NO);
}
ret = gpio_direction_input(GPIO_NO);
if(ret < 0)
{
printk(KERN_INFO "%s: Setting GPIO direction to input failed\n", __func__);
return -1;
}
else
{
printk(KERN_INFO "%s: Direction of GPIO_%d set to input\n", __func__, GPIO_NO);
}
GPIO_IRQ = gpio_to_irq(GPIO_NO);
if(GPIO_IRQ < 0)
{
printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ failed\n", __func__, GPIO_NO);
return -1;
}
else
{
printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ_%d successful\n", __func__, GPIO_NO, GPIO_IRQ);
}
if((request_irq(GPIO_IRQ, ten_ms_int, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL)))
{
printk(KERN_ALERT "%s: requeseting GPIO_IRQ %d failed\n", __func__, GPIO_IRQ);
return -1;
}
else
{
printk(KERN_INFO "%s: requesting GPIO_IRQ %d successful\n", __func__, GPIO_IRQ);
}
irqreturn_t ten_ms_int(int irq, void *dev_id)
{
T_UINT32 l;
/* Enable spi channel */
l = ioread32(spi_base + SPI_CHCONF0);
l |= SPI_CHCONF0_FORCE;
iowrite32(l, (spi_base + SPI_CHCONF0));
l = ioread32(spi_base + SPI_CHCTRL0);
l |= SPI_CHCTRL_EN;
iowrite32(l, (spi_base + SPI_CHCTRL0));
/* Enable dma channel 0 */
l = ioread32(sdma_base + SDMA_CCR(CHANNEL0));
l |= SDMA_CCR_ENABLE;
iowrite32(l, sdma_base + SDMA_CCR(CHANNEL0));
/* Enable dma channel 1 */
l = ioread32(sdma_base + SDMA_CCR(CHANNEL1));
l |= SDMA_CCR_ENABLE;
iowrite32(l, sdma_base + SDMA_CCR(CHANNEL1));
//printk(KERN_INFO "%s: 10ms interrupt detected %d\n", __func__, irq); /* I know that I've to remove this printk statement */
return IRQ_HANDLED;
}
GPIO_39 gehört zur Bank GPIO2 und die entsprechende Interrupt-Nummer ist 32. Aber der Rückgabewert von gpio_to_irq()
ist 199. Dies ist ein weiterer Grund zur Besorgnis.
Bitte lassen Sie mich wissen, wenn etwas im Code falsch ist oder wenn ich etwas verpasst habe.
Ihr Code sieht meistens OK aus. Ich denke dein erster iowrite ist wahrscheinlich im besten Fall unnötig, was soll er tun? Haben Sie Ihre Pin-Multiplex-Einstellungen überprüft und verifiziert, dass Sie das Interrupt-Signal als Wert lesen können (z. B. mit der Userspace-Schnittstelle)? – slobobaby
Der erste iowrite ist der Pin-Muxing-Teil. –
Wenn Sie die Userspace-Schnittstelle verwenden, können Sie den externen Signalpegel richtig lesen? – slobobaby