UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
9,034 Views
Registered: ‎02-12-2015

UIO not "reading" interrupt petalinux Zynq

Jump to solution

Hello,

 

I have quite a simple PL design consisting of a Zynq module, a custom AXI peripheral whose registers connect to my board's LEDs and an interrupt generator which generates pulses connected to the IRQ_F2P port of the zynq.

 

I have a UIO component which can set the registers happily and I see the LEDs change as expected. However, when I try and use an interrupt to control the UIO component, it hangs on the read() call.

My UIO code is basically:

 

 

fd = open("/dev/uio0", O_RDWR);

ptr = (volatile unsigned *)mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

unsigned int count = 0x0;

while(1){

    unsigned int nb = read(fd, &count, sizeof(count));

    .. handle interrupt

}

 

system-top:

/dts-v1/;
/include/ "system-conf.dtsi"
/ {
      uio_axi_ps_ready@43C00000 {
      compatible = "generic-uio";
      reg = < 0x43C00000 4096 >;
      interrupts = < 0 59 1 >;
      interrupt-parent = <&intc>;
   };
};

 

I chose 59 as I the zynq module seems to suggest it's first interrupt is at number 91. (91-32=59). Not sure about &intc - I see lots of examples with &gic as the interrupt parent but I get an error during the kernel build with this setting...

 

Any ideas why it just hangs? I've mapped my interrupt generator output to an LED and it seems to be working as I expect - 1 pulse (enabled for 60 us) every 4ms.

 

Any help I'd be very grateful, thanks.

 

 

 

0 Kudos
1 Solution

Accepted Solutions
Adventurer
Adventurer
16,623 Views
Registered: ‎02-12-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Got it working...

 

I think the problem was I wasn't doing a write to clear the interrupt before the read. Also, changed the count variable to an int rather than unsigned int and used ssize_t for the return value but doubt this would make much difference.

 

Anyway, the code...

 

int main(void)
{
  int fd;
  volatile unsigned *ptr;

  fd = open("/dev/uio0", O_RDWR);
  if (fd < 1) {
    fprintf(stderr,"Invalid UIO device file.\n");
    return -1;
  }

  // mmap the UIO device
  ptr = (volatile unsigned *)mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

  fprintf(stdout, "\nTurn LED on 0x%04x \n", ptr);
  *ptr = 0x1;
  unsigned int value = *ptr;
  int count = 1;
  while(1)
  {
    ssize_t nb = write(fd, &count, sizeof(count));
    fprintf(stdout, "\n Wrote\n");
    if(nb < sizeof(count))
    {
        fprintf(stdout, "\n IRQ Write Failed\n");
        close(fd);
        return -1;
    }
    nb = read(fd, &count, sizeof(count));
    fprintf(stdout, "\n Read\n");
    if(nb == sizeof(count))
    {
        fprintf(stdout, "\n IRQ Read! \n");
        if(value & 0x1 == 0x1)
        {
            *ptr = 0x0;
        }
        else
        {
            *ptr = 0x1;
        }
        value = *ptr;
    }
  }
}

View solution in original post

0 Kudos
6 Replies
Adventurer
Adventurer
9,027 Views
Registered: ‎02-12-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Just to add - 

 

when I do cat /proc/interrupts I see:

167:   0   0   GIC   91   Edge   uio_axi_ps_ready (my UIO component)

 

And when I try to use <&gic> as interrupt parent in system-top.dts

 

I get the error:

[ERROR] ERROR (phandle_references): Reference to non-existent node or label "gic"

 

 

0 Kudos
Adventurer
Adventurer
9,010 Views
Registered: ‎12-03-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Hi,

 

The first thing you should check is that you are using the correct interrupt number in your DTS. Find the port number that you have connected to interrupt generator to (IRQ_F2P[15:0]). The port numbers then map to PS IRQ [91:84], [68:61], and the device tree entry for the interrupt number has to have 32 subtracted. 

So your device tree entry for the interrupt is correct if the PL interrupt is connected to IRQ_F2P port 15.

After that I would check the bootargs line in system-conf.dtsi. The "generic-uio" compatible string doesn't work in the newer kernels. It should look like this:

 

chosen {
bootargs = "console=ttyPS0,115200 earlyprintk uio_pdrv_genirq.of_id=generic-uio";
};

 

If not, add it to system-top.dts.

 

Ron

0 Kudos
Highlighted
Adventurer
Adventurer
9,005 Views
Registered: ‎02-12-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Hi Ron,

 

Thanks for the reply.

 

So, I noticed in my PL design the Interrupt line was connected to IRQ_F2P[0:0], so I guess number 61 instead of 91.

 

I changed my dts accordingly so:

interrupts = < 0 29 1 >;

 

My .dtsi includes uio_pdrv_genirq.of_id=generic-uio

 

On running my UIO component, I get the same hang on the read command as before. However, I noticed this time that cat /proc/interrupts this time gives:

167:          2          0       GIC  61 Edge      uio_axi_ps_ready

 

Does this mean it has seen 2 interrupts? So, still stumped as to why the read does not return...

 

0 Kudos
Adventurer
Adventurer
8,989 Views
Registered: ‎12-03-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Yes, 2 interrupts have occurred. 

Not sure where to go next. Double check all the connections (interrupts and clocks) on the PL side and make sure that any needed clocks are enabled.

 

0 Kudos
Adventurer
Adventurer
16,624 Views
Registered: ‎02-12-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Got it working...

 

I think the problem was I wasn't doing a write to clear the interrupt before the read. Also, changed the count variable to an int rather than unsigned int and used ssize_t for the return value but doubt this would make much difference.

 

Anyway, the code...

 

int main(void)
{
  int fd;
  volatile unsigned *ptr;

  fd = open("/dev/uio0", O_RDWR);
  if (fd < 1) {
    fprintf(stderr,"Invalid UIO device file.\n");
    return -1;
  }

  // mmap the UIO device
  ptr = (volatile unsigned *)mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

  fprintf(stdout, "\nTurn LED on 0x%04x \n", ptr);
  *ptr = 0x1;
  unsigned int value = *ptr;
  int count = 1;
  while(1)
  {
    ssize_t nb = write(fd, &count, sizeof(count));
    fprintf(stdout, "\n Wrote\n");
    if(nb < sizeof(count))
    {
        fprintf(stdout, "\n IRQ Write Failed\n");
        close(fd);
        return -1;
    }
    nb = read(fd, &count, sizeof(count));
    fprintf(stdout, "\n Read\n");
    if(nb == sizeof(count))
    {
        fprintf(stdout, "\n IRQ Read! \n");
        if(value & 0x1 == 0x1)
        {
            *ptr = 0x0;
        }
        else
        {
            *ptr = 0x1;
        }
        value = *ptr;
    }
  }
}

View solution in original post

0 Kudos
Contributor
Contributor
7,875 Views
Registered: ‎05-27-2015

Re: UIO not "reading" interrupt petalinux Zynq

Jump to solution

Hi,

 

I do not understand why you need to write in your while loop. The custom IP you created should generate the interrupt and you acknowledge the pending interrupt by reading the uio device file. So, I don't understand the write. Can you explain please ?

Are you able to enable/disable interrupts from Linux ?

 

Best Regards,
M.Abdul WAHAB

0 Kudos