This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x interrupt detection

Dear all,

I have a problem with interrupt handling on am335x .

The environment is:

- kernell: builded from the TI sdk

- rootfs: customized ubuntu

We have to connect some spi devices to the spi1 bus. The am335x is the master so the slave ask for attention trough an interrupt pin and.. we need to detect that interrupt at least each millisecond.

So the spi device lower a pin, the am335x must detect the falling edge and answer in less than half millisecond.

I used the "poll" function for that pin (in a forked thread) but is very lazy, so I adopted the solution to manually poll the memory register DATA_IN of the right gpio-bank (always in a separated thread) and it is quite faster.. but not fast enough.

What is the best way to listen for incoming interrupt? It is correct to do this at user space?

After the detection of that interrupt I have to start an SPI communication.

Any advice would be very appreciated.

Regards

Giuseppe

  • Hi Giuseppe,

    I can suggest to try and do it in a kernel module. The module should look something like this:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/mm.h>
    #include <linux/slab.h>
    #include <linux/interrupt.h>

    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_AUTHOR("Name");

    static int irq;
    static char *interface;

    module_param(interface, charp, S_IRUGO);
    MODULE_PARM_DESC(interface, "A SPI interface");
    module_param(irq, int, S_IRUGO);
    MODULE_PARM_DESC(irq, "The IRQ of the SPI interface");

    static irqreturn_t my_irq_handler(int irq, void *dev_id)
    {
        printk(KERN_INFO "Interrupt #%ld\n", irq);
        return IRQ_NONE;
    }

    static int __init my_init(void)
    {
        int err = 0;
        printk(KERN_INFO "********** INITIALIZING DRIVER **********\n");
        err = request_irq(irq, my_irq_handler, IRQF_TRIGGER_FALLING | IRQF_SHARED, interface, &irq);
        printk(KERN_ERR "request_irq returned ERR: %d\n", err);
        if (err) {
            printk(KERN_ERR "My IRQ request: cannot register IRQ %d\n", irq);
            return -EIO;
        }
        printk(KERN_INFO "My request on IRQ %d succeeded\n", irq);

        return 0;
    }

    static void __exit my_exit(void)
    {
        printk(KERN_INFO "********** EXITING DRIVER **********\n");
        free_irq(irq, &irq);
        printk(KERN_INFO "Freeing IRQ %d\n", irq);
    }

    module_init(my_init);
    module_exit(my_exit);

    Best regards,
    Miroslav

  • Thanks a lot but,

    How can the user space know that an incoming interrupt is arrived?

    I'm not so used to kernell programming

    Regards

    GZ

  • As far as I know, the user space way for interrupt handling is actually polling and you have already tried this. What I found here (first answer from Norman Wong) is that this method cannot really be used for fast changing signals (less than 10ms). I guess you will need to do it in a kernel module if you wish to be faster.

    Best regards,
    Miroslav