Forum Discussion

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

uclinux PIO device driver interrupt handler not execute

Hi,

Thanks in advance for any help I can get. I have a NIOS2 w/MMU running uClinux v3.7. It's a DE2-115 development kit with Cyclone IV FPGA. I use the PIO megafunction to monitor input rising edge from the SMA pin and generate interrupt IRQ. I developed an uClinux device driver in the misc folder. All seem correct and compile, but the handler function doesn't seem like it was executed when I generate a pulse signal to the SMA.

Here is my device driver code:

in the probe function call

- res_mem = platform_get_resource(pdev, IORESURCE_MEM, 0)

- request_mem_region(res_mem->start, resource_size(res_mem), "GPIO_NAME")

- of_iomap(pdev->dev.of_node, 0);

- irq = irq_ofparse_and_map(pdev->dev.of_node, 0)

- request_irq(irq, pps_gpio_irq_handler, 1, "GPIO_NAME", NULL);

in the interrupt handler call

static irqreturn_t pps_gpio_irq_handler(int irq, void *dev_id)

{

printk(KERN_ALERT "Trigger");

return IRQ_HANDLED;

}

If I execute command "cat /proc/interrupt", the driver was successful requested.

2: 0 NIOS2-INTC GPIO_NAME

As you can see, the interrupt count didn't get incremented and "Trigger" was never print out after I apply a pulse signal to the SMA port. Is there a function call I am missing? or anything that I miss?

14 Replies

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

    Hi,

    --- Quote Start ---

    Do you know a good way to get time(second/usecond)? I tried to use the do_gettimeofday function call in the interrupt handler but with random timestamp return. Sometime it jump back time as well. If you may know, can you kindly point me to a right direction?

    --- Quote End ---

    What 'jump back time' means?

    
    /**
     * do_gettimeofday - Returns the time of day in a timeval
     * @tv:		pointer to the timeval to be set
     *
     * NOTE: Users should be converted to using getnstimeofday()
     */
    void do_gettimeofday(struct timeval *tv)
    {
    	struct timespec now;
    	getnstimeofday(&now);
    	tv->tv_sec = now.tv_sec;
    	tv->tv_usec = now.tv_nsec/1000;
    }
    

    'tv_sec' will not increase monotonously ? How does the command 'date' response in your shell ?

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

    Hi Kazu,

    The jump back time I have experience with do_gettimeofday is captured in attached jpg. I apologize the terminology I use may cause confusion. The timestamp showing unreliable outcome. The major concern I have here is the GPIO receive pulse signal supposedly every 100ms so the interrupt handler get trigger on each pulse's rising edge and grab the current timestamp. Nonetheless, as the picture have show, it receive interrupt in 4, 11, 20, or even 40 msec, but not 100msec in between. The input signal come from a signal generator and verified with a scope to ensure each pulse is 100msec in between. I am trying to narrow down the cause of this problem by trying various setting to request_irq and using jiffies to see any different. The results are the same. Is it because I am not suppose to call timestamp in an interrupt handler? or was it because the system can't handle the fast pace pulse trigger? Any help is greatly appreciated.

    Following is my interrupt handler:

    static irqreturn_t gpio_irq_handler(int irq, void *dev_id)

    {

    int ipending = __builtin_rdctl(4);

    if((ipending & 0x03) > 0)

    {

    *(base_addr + 3) = 0;//Clear the Edge Capture

    do_gettimeofday(&tv);

    time_to_tm(tv.tv_sec, 0, &broken);

    printk ("%02d:%02d:%02d:%03ld\n",broken.tm_hour, broken.tm_min, broken.tm_sec, (tv.tv_usec/1000));

    ///////////////////////////////////////////////////////////////////////////////

    }

    return IRQ_HANDLED;

    }

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

    Hi,

    --- Quote Start ---

    Following is my interrupt handler:

    static irqreturn_t gpio_irq_handler(int irq, void *dev_id)

    {

    int ipending = __builtin_rdctl(4);

    if((ipending & 0x03) > 0)

    {

    *(base_addr + 3) = 0;//Clear the Edge Capture

    do_gettimeofday(&tv);

    time_to_tm(tv.tv_sec, 0, &broken);

    printk ("%02d:%02d:%02d:%03ld\n",broken.tm_hour, broken.tm_min, broken.tm_sec, (tv.tv_usec/1000));

    ///////////////////////////////////////////////////////////////////////////////

    }

    return IRQ_HANDLED;

    }

    --- Quote End ---

    Did you take account of the execution time of 'printk' ? Please consider what will happen if it will take over 100msec. And you don't need to check 'ipending', because the kernel checks it and calls this handler. But it's better for you to check whether the edge is really captured or not.

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

    Hi Kazu,

    I have experience missing receive bytes using UART RS232 port on uClinux running NIOS2 /f. I implemented a loopback application to send 128 bytes hex data from ttyA0 (RS232 port) and receive on ttyA5 (RS232 port). This is a DE2-115 development kit. The IRQ for both port is 1 and 2. I have a JTAG for nios2-terminal, but it's irq is 3. I have disabled the flow control (ctsrts, xon/xoff,etc), but each loopback test I do, I always missing 10 to 11 bytes. However, if I send less than 10 bytes of data, I have higher chance of success getting the same bytes across. I have heard I need a FIFO MEGAIP for the design but there no current uClinux driver support it. If you know of this problem and have a solution to it, please kindly let me know what I am missing?

    Thanks,

    Yeung