element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Avnet Boards Forums
  • Products
  • Dev Tools
  • Avnet Boards Community
  • Avnet Boards Forums
  • More
  • Cancel
Avnet Boards Forums
Software Application Development AXI GPIO Interrupt
  • Forum
  • Documents
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Avnet Boards Forums to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • Replies 9 replies
  • Subscribers 329 subscribers
  • Views 3264 views
  • Users 0 members are here
Related

AXI GPIO Interrupt

Former Member
Former Member over 10 years ago

Hello everyone,

i'd like to use an interrupt from a pushbutton. The buttons are connected via axi_gpio (IOCarrierCard). They works in uio in petalinux. I can read the value of the 4 pushbuttons in uio.
Now i try to detect an interrupt.
I enabled interrupts in axi_gpio ip and fabric interrupts and IRQ_F2P in zynq processing system. After that i connected them.
In the kernel config i activated "userspace i/o drivers", "userspace i/o platform driver with irq..." and "xilinx axi performance monitor driver".
My system-top.dts looks like:

&axi_gpio_0 {
ttcompatible = "generic-uio";
                interrupts = <0 29 4>;
ttinterrupt-parent = <&intc>;
t};

After booting the system and push the buttons, i don't see an interrupt with "cat /proc/interrupt" (i see  61:          0          0       GIC  61  gpio ).
I also try to write a user application and wait for an interrupt with:

int irq_count = 0;
... open and map uio ....
if(read(fd, &irq_count, 4) != 4)
t{
ttperror("read uio0");
               
t}
printf("Interrupt!");

I think after receiving an interrupt, the programm should print "Interrupt" but nothing happpens.

I followed this tutorial: http://svenand.blogdrive.com/archive/150.html#.VWRsV0YQjph


My setup:
Petalinux, SDK, Vivado 2014.4
Microzed Board with IOCarrier Card

Thanks for your answers,
Sebastian

  • Sign in to reply
  • Cancel
Parents
  • Former Member
    0 Former Member over 10 years ago

    Hi Kevin,

    thank you for your answer. Interrupts works now but i have a problem with printf() in a while loop. In the function wait_for_interrupt() is a breakpoint. If i push a button, read() unblocks the programm and wait at the breakpoint but printf() doesn't work. If i try this without a while loop, it works. With a for loop, i can push a button i times and after that, the printf() output follows i times. DO you have an idea for that?

    regards,
    Sebastian


    For each other, here is my hardware, the device tree and the code for a axi gpio interrupt.
    It's important to load your drivers at the kernel manual with the shell command:
    modprobe uio_pdrv_genirq.of_id="generic-uio"
    Furthermore it's important to configure and enable the interrupts at your code. After an interrupt, the interrupts have to reenable.

    Hardware:
    http://up.picr.de/22058574ln.jpg

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

    &axi_gpio_0 {
    t compatible = "generic-uio";
    t reg = <0x41200000 0x10000>;
    tinterrupt-parent = <&intc>;
    tinterrupts = <0 29 4>;
    };

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <fcntl.h>

    #define GPIO_MAP_SIZE tt0x10000
    #define GPIO_DATA_OFFSETt0x00
    #define GPIO_TRI_OFFSETtt0x04
    #define GPIO_DATA2_OFFSETt0x08
    #define GPIO_TRI2_OFFSETt0x0C
    #define GPIO_GLOBAL_IRQtt0x11C
    #define GPIO_IRQ_CONTROLt0x128
    #define GPIO_IRQ_STATUStt0x120


    inline void gpio_write(void *gpio_base, unsigned int offset, unsigned int value)
    {
    t*((volatile unsigned *)(gpio_base + offset)) = value;
    }

    inline unsigned int gpio_read(void *gpio_base, unsigned int offset)
    {
    treturn *((volatile unsigned *)(gpio_base + offset));
    }

    unsigned int get_memory_size(char *sysfs_path_file)
    {
    tFILE *size_fp;
    tunsigned int size;

    t// open the file that describes the memory range size that is based on the
    t// reg property of the node in the device tree

    tsize_fp = fopen(sysfs_path_file, "r");

    tif (!size_fp) {
    ttprintf("unable to open the uio size file
    ");
    ttexit(-1);
    t}

    t// get the size which is an ASCII string such as 0xXXXXXXXX and then be stop
    t// using the file

    tfscanf(size_fp, "0x%08X", &size);
    tfclose(size_fp);

    treturn size;
    }

    void wait_for_interrupt(int fd, void *gpio_ptr)
    {
    tint pending = 0;
    tint reenable = 1;
    tunsigned int reg;

    t// block on the file waiting for an interrupt */
    tread(fd, (void *)&pending, sizeof(int));
    t////Breakoint/////
    tprintf("Interrupt!");

    t// the interrupt occurred for the 1st GPIO channel so clear it
    treg = gpio_read(gpio_ptr, GPIO_IRQ_STATUS);
    tif (reg)
    ttgpio_write(gpio_ptr, GPIO_IRQ_STATUS, 1); //


    t// re-enable the interrupt in the interrupt controller thru the
    t// the UIO subsystem now that it's been handled

    twrite(fd, (void *)&reenable, sizeof(int));

    }

    int main()
    {
    tint uio0_fd;
    tvoid *ptr;
    tint gpio_size;
    tint reenable = 1;


    tif ((uio0_fd = open("/dev/uio0", O_RDWR)) < 0)
    t{
    ttperror("open uio0");
    t}
    telse{printf("uio0 opened
    ");}

    tgpio_size = get_memory_size("/sys/class/uio/uio0/maps/map0/size");

    tptr = mmap(NULL, gpio_size, PROT_READ|PROT_WRITE, MAP_SHARED, uio0_fd, 0);

    tif (ptr == MAP_FAILED) {
    tttprintf("Mmap call failure.
    ");
    tttreturn -1;
    tt}
    tgpio_write(ptr, GPIO_TRI_OFFSET, 0xFF); // GPIO Channel 1 input

    tgpio_write(ptr, GPIO_GLOBAL_IRQ, 0x80000000); // GIER, 31. Bit
    tgpio_write(ptr, GPIO_IRQ_CONTROL, 1);  // Channel 1 Interrupt enable

    twrite(uio0_fd, (void *)&reenable, sizeof(int)); // 2nd start

    t//wait for interrupt
    twhile(1)
    t{
    ttwait_for_interrupt(uio0_fd, ptr);
    t}


    tmunmap(ptr, gpio_size);

    treturn 0;
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • Former Member
    0 Former Member over 10 years ago

    Hi Kevin,

    thank you for your answer. Interrupts works now but i have a problem with printf() in a while loop. In the function wait_for_interrupt() is a breakpoint. If i push a button, read() unblocks the programm and wait at the breakpoint but printf() doesn't work. If i try this without a while loop, it works. With a for loop, i can push a button i times and after that, the printf() output follows i times. DO you have an idea for that?

    regards,
    Sebastian


    For each other, here is my hardware, the device tree and the code for a axi gpio interrupt.
    It's important to load your drivers at the kernel manual with the shell command:
    modprobe uio_pdrv_genirq.of_id="generic-uio"
    Furthermore it's important to configure and enable the interrupts at your code. After an interrupt, the interrupts have to reenable.

    Hardware:
    http://up.picr.de/22058574ln.jpg

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

    &axi_gpio_0 {
    t compatible = "generic-uio";
    t reg = <0x41200000 0x10000>;
    tinterrupt-parent = <&intc>;
    tinterrupts = <0 29 4>;
    };

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <fcntl.h>

    #define GPIO_MAP_SIZE tt0x10000
    #define GPIO_DATA_OFFSETt0x00
    #define GPIO_TRI_OFFSETtt0x04
    #define GPIO_DATA2_OFFSETt0x08
    #define GPIO_TRI2_OFFSETt0x0C
    #define GPIO_GLOBAL_IRQtt0x11C
    #define GPIO_IRQ_CONTROLt0x128
    #define GPIO_IRQ_STATUStt0x120


    inline void gpio_write(void *gpio_base, unsigned int offset, unsigned int value)
    {
    t*((volatile unsigned *)(gpio_base + offset)) = value;
    }

    inline unsigned int gpio_read(void *gpio_base, unsigned int offset)
    {
    treturn *((volatile unsigned *)(gpio_base + offset));
    }

    unsigned int get_memory_size(char *sysfs_path_file)
    {
    tFILE *size_fp;
    tunsigned int size;

    t// open the file that describes the memory range size that is based on the
    t// reg property of the node in the device tree

    tsize_fp = fopen(sysfs_path_file, "r");

    tif (!size_fp) {
    ttprintf("unable to open the uio size file
    ");
    ttexit(-1);
    t}

    t// get the size which is an ASCII string such as 0xXXXXXXXX and then be stop
    t// using the file

    tfscanf(size_fp, "0x%08X", &size);
    tfclose(size_fp);

    treturn size;
    }

    void wait_for_interrupt(int fd, void *gpio_ptr)
    {
    tint pending = 0;
    tint reenable = 1;
    tunsigned int reg;

    t// block on the file waiting for an interrupt */
    tread(fd, (void *)&pending, sizeof(int));
    t////Breakoint/////
    tprintf("Interrupt!");

    t// the interrupt occurred for the 1st GPIO channel so clear it
    treg = gpio_read(gpio_ptr, GPIO_IRQ_STATUS);
    tif (reg)
    ttgpio_write(gpio_ptr, GPIO_IRQ_STATUS, 1); //


    t// re-enable the interrupt in the interrupt controller thru the
    t// the UIO subsystem now that it's been handled

    twrite(fd, (void *)&reenable, sizeof(int));

    }

    int main()
    {
    tint uio0_fd;
    tvoid *ptr;
    tint gpio_size;
    tint reenable = 1;


    tif ((uio0_fd = open("/dev/uio0", O_RDWR)) < 0)
    t{
    ttperror("open uio0");
    t}
    telse{printf("uio0 opened
    ");}

    tgpio_size = get_memory_size("/sys/class/uio/uio0/maps/map0/size");

    tptr = mmap(NULL, gpio_size, PROT_READ|PROT_WRITE, MAP_SHARED, uio0_fd, 0);

    tif (ptr == MAP_FAILED) {
    tttprintf("Mmap call failure.
    ");
    tttreturn -1;
    tt}
    tgpio_write(ptr, GPIO_TRI_OFFSET, 0xFF); // GPIO Channel 1 input

    tgpio_write(ptr, GPIO_GLOBAL_IRQ, 0x80000000); // GIER, 31. Bit
    tgpio_write(ptr, GPIO_IRQ_CONTROL, 1);  // Channel 1 Interrupt enable

    twrite(uio0_fd, (void *)&reenable, sizeof(int)); // 2nd start

    t//wait for interrupt
    twhile(1)
    t{
    ttwait_for_interrupt(uio0_fd, ptr);
    t}


    tmunmap(ptr, gpio_size);

    treturn 0;
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube