Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

IRQs

hey everybody,

is there an easy guide to use IP core's IRQ in uClinux?

do I need an interrupt handler or read from a specific location?

thanks :)

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The normal way to handle IRQs is doing a Kernel driver. As the OS handle the ISR entry and exit for you, here, the C code you do is not different from what is done with other architectures. There are lot of examples in the Kernel sources.

    Is that what you want to do ?

    I learned that "uio" should allow for a kind of ISR in s user land application, but I never did look into that.

    -Michael
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have an IP assigned to IRQ 2,

    I tried to get an interrupt through my kernel driver with no luck so far

    I thought maybe I missed something, it's my first try with interrupts in uclinux

    could you direct me to those code examples?

    thanks

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Did you read "Linux Device Drivers" 3rd Edition by Rubini and friends ?

    Here you learn how to register an ISR with the Kernel and youl be pointed to exeamples.

    -Michael
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    hey Michael,

    this is really helpful, thanks

    but I have a small problem

    when I compile my code it says that SA_SHIRQ is undeclared... same goes for SA_INTERRUPT

    any idea why?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The irq header changed a lot since the book published. Please check current kernel header. You may look at some drivers for the usage.

    linux-2.6/include/linux/interrupt.h

    - Hippo
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    you're right, it's completly different now

    I tried to write the simplest thing I could

    in the __init function:

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    /* register interrupt */

    if (request_irq(UART_IRQ, uart_pio_isr, IRQF_DISABLED, "uart_pio", (void *)(uart_pio_isr)))

    {

    printk("uart_pio: unable to register interrupt %d\n", UART_IRQ);

    return -1;

    }[/b]

    --- Quote End ---

    above it:

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    static irqreturn_t uart_pio_isr(int irq, void *dev_id, struct pt_regs *regs)

    {

    int data;

    data = inb(UART);

    printk("<>Interrupt recieved, ");

    printk("data is %d<>\n",data);

    return IRQ_HANDLED;

    }[/b]

    --- Quote End ---

    but I still can&#39;t get interrupts... I know it&#39;s not a hw problem

    does this warning has something to do with it?

    <div class='quotetop'>quote </div>

    --- quote start ---

    warning: passing argument 2 of &#39;request_irq&#39; from incompatible pointer type

    --- Quote End ---

    [/b]

    thanks :huh:
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    My ISR function signatures look like this:

    static irqreturn_t isr_handler(int irq, void *data)

    Yours has one more parameter. That is probably the cause of your warning, but I do not know if that is the root cause.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    well that did solve the warning but not the problem

    I tried something even simpler than before

    I added PIO for switches and enabled it to generate interrupt (edge)

    and still, no sign of life

    I can read from it and write to a similar PIO module

    but no interrupts

    is it a code problem?

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    #include </home/atop/nios2-linux/uClinux-dist/linux-2.6.x/include/asm-nios2/nios2.h> /* My system */# include <linux/kernel.h> /* We&#39;re doing kernel work */# include <linux/module.h> /* Specifically, a module */# include <linux/fs.h># include <linux/configfs.h># include <linux/cdev.h># include <linux/interrupt.h> /* Using interrupts (request_irq,free_irq...),(IRQF_SHARED,IRQF_DISABLED...) */# include <linux/init.h> /* For __init and __exit functions */# include <linux/slab.h># include <asm/uaccess.h> /* For copy_from_user and copy_to_user */# include <asm/signal.h> # include <asm/io.h>

    # define switches na_Switches# define switches_IRQ na_Switches_irq# define switches_MAJOR 247

    static int Device_Open = 0; //indicate whether the device is open

    static ssize_t switches_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)

    {

    char buffer;

    buffer = inb(switches);

    copy_to_user(buf,&buffer,1);

    /* Changing reading position as best suits */

    if (*ppos == 0)

    {

    *ppos+=1;

    return 1;

    }

    else

    {

    return 0;

    }

    }

    static int switches_open(struct inode *inode, struct file *file)

    {

    # ifdef DEBUG

    printk(KERN_INFO "device_open(%p)\n", file);

    # endif

    if (Device_Open)

    return 1; //return failure

    Device_Open++;

    try_module_get(THIS_MODULE);

    return 0; //return success

    }

    static int switches_release(struct inode *inode, struct file *file)

    {

    # ifdef DEBUG

    printk(KERN_INFO "device_release(%p,%p)\n", inode, file);

    # endif

    Device_Open-=1;

    module_put(THIS_MODULE);

    free_irq(switches_IRQ, NULL);

    return 0; //return success

    }

    static struct file_operations switches_fops =

    {

    .read = switches_read,

    .write = NULL,

    .open = switches_open,

    .release = switches_release

    };

    /*********************************INTERRUPT************************************/

    static irqreturn_t switches_pio_isr(int irq, void *dev_id)//, struct pt_regs *regs)

    {

    int data;

    printk("<>Interrupt recieved, ");

    data = inb(switches);

    printk("data is %d<>\n",data);

    return IRQ_HANDLED;

    }

    /******************************************************************************/

    static int __init switches_init(void)

    {

    if(register_chrdev (switches_MAJOR, "switches", &switches_fops))

    {

    printk("<>could not register switches module... crap<>\n");

    }

    /* register interrupt */

    if (request_irq(switches_IRQ, switches_pio_isr, IRQF_DISABLED, "switches", NULL))

    {

    printk("switches_pio: unable to register interrupt %d\n", switches_IRQ);

    return -1;

    }

    printk("<>switches module registered... yey<>\n");

    return 0;

    }

    static void __exit switches_exit(void)

    {

    unregister_chrdev(switches_MAJOR, "switches");

    printk("<>switches module unloaded<>\n");

    }

    module_init (switches_init);

    module_exit (switches_exit);

    MODULE_LICENSE("GPL");

    MODULE_DESCRIPTION("switches...");

    MODULE_AUTHOR("Asaf B.");[/b]

    --- Quote End ---

    I know I&#39;m probably being annoying but I really haven&#39;t got a clue what&#39;s wrong :(
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    I think that I am with a similar problem that you have or you have had. Do you solve it?? If you have solved it can you explain which was the problem??

    Thanks a lot.