zhemao / interrupt_example

An example of how to use Avalon interrupts on the Cyclone V FPGA
13 stars 8 forks source link

Cant install Interrupt example on the Altera SoC Dev board #1

Open bstarck opened 9 years ago

bstarck commented 9 years ago

Hello Howard,

Many thanks for your Cyclone 5 tutorials they have been a great help.

I have been looking at your interrupt example and have successfully run it on the Arrow Sockit board. However I am now trying to run it on the Altera SoC Development board and have run into difficulties. When I run the command, insmod ./fpga_uinput.ko , I get the error: Error: could not insert module fpga_uinput.ko: Invalid parameters.

I am using the 14.0 SD card image, provided by Rocketboards. uname -a Linux socfpga 3.13.0-00298-g3c7cbb9 #1 SMP Tue Jun 24 09:29:53 MYT 2014 armv7l GNU/Linux modinfo fpga_uinput.ko filename: /home/root/fpga_uinput.ko license: Dual BSD/GPL depends:
vermagic: 3.13.0-00298-g3c7cbb9 SMP mod_unload ARMv7 p2v8

Unfortunately I have been unable to get any further information about what could be causing the module to fail with Invalid Parameters.

Are you able to shed any light on this?

Many thanks. Brian

bstarck commented 9 years ago

Adding one additional bit of information: The interrupt module worked fine on the Altera SoC board when I used the 13.1 SD card image!

Brian

zhemao commented 9 years ago

If it works with one SD card image and not another, my guess is that your kernel version numbers are mismatched. What version of the kernel are you compiling the module against? You might have to change it in order to use it with the newer SD card image.

bstarck commented 9 years ago

Thanks for the response. I did have kernel version problems, but that was fixed by rebuilding all the modules. I have been doing a bit more investigating and have managed to narrow the problem down to the IRQ number.

define UINPUT_INT_NUM 72, if I change the number to say 62, then I can load the module. Obviously at this point the IRQ is now no longer attached to the the FPGA IRQ0, but at least it loads.

I am struggling to find what is missing that defines the FPGA IRQ numbers. Thanks Brian

zhemao commented 9 years ago

Sorry about that, I had the interrupt numbers hard-coded for the SoCKit board. You will have to look in the datasheets to figure out where the FPGA interrupts start on the new board.

dkapitel commented 9 years ago

Hi Howard, I have the same problem with the Sockit Dev Board. I am using the Linaro rootfs and kernel 3.10.31-LTSI.

root@linaro-nano:/home/linaro# uname -a Linux linaro-nano 3.10.31-ltsi-05035-g801a40f #2 SMP Mon Jun 29 01:45:01 PDT 2015 armv7l armv7l armv7l GNU/Linux root@linaro-nano:/home/linaro# modinfo fpga_uinput.ko filename: /home/linaro/fpga_uinput.ko license: Dual BSD/GPL depends: vermagic: 3.10.31-ltsi-05035-g801a40f SMP mod_unload ARMv7 p2v8

If I use the #define UINPUT_INT_NUM 72 i cant load the module. The manual says that fpga interrupts start at 72. If i use the Interrupt number 2 in QSYS and #define UINPUT_INT_NUM 74 I can load the module. After loading the module the Sockit freezes and i get the following message: root@linaro-nano:/home/linaro# insmod fpga_uinput.ko INFO: rcu_sched self-detected stall on CPU { 0} (t=2100 jiffies g=4294967270 c=4294967269 q=407) INFO: rcu_sched self-detected stall on CPU { 0} (t=8403 jiffies g=4294967270 c=4294967269 q=3681)

Is it possible that the module runs in a loop in function fpga_uinput_show, because the down_trylock never succeeds? if (down_trylock(&interrupt_mutex)) return -EAGAIN;

Can you say me if it is necessary to modify the device tree so that i have access to the interrupt?

Thanks Daniel

bstarck commented 9 years ago

Have a look at the dts file, it will list all the IRQ's you have attached in your QSys design. If the IRQ you are looking for does not appear then you will need to rebuild your device tree.

Taken from http://xillybus.com/tutorials/device-tree-altera-soc-cyclone Interrupt numbers explained The HPS’ interrupt numbers are listed in table 6-3 in Cyclone V Device Handbook, vol. 3 (these numbers match those that appear in /proc/interrupts). The interrupts from the FPGA are listed as FPGA_IRQn, where nn goes from 0 to 63. The first 32 interrupts are related to the first 32-bit wide interrupt vector going to the HPS (a.k.a. f2h_irq0) and the following 32 interrupts relate to the second vector (f2h_irq1). FPGA_IRQ00 is mapped to interrupt number 72 of the processor, and these numbers are incremented along with n. Since the bottom line rule in the post about Zynq was to subtract 32 from the processor’s interrupt number, we have a DTS identifier of 72-32=40 for the n=0. As for interrupt zero on f2h_irq1, it’s n=32, so we have 104-32=72.

Example of a number of pio's listed in the dts file:

        pio_0: gpio@0x100000000 {
            compatible = "altr,pio-14.1", "altr,pio-1.0";
            reg = <0x00000001 0x00000000 0x00000010>;
            interrupt-parent = <&hps_0_arm_gic_0>;
            interrupts = <0 40 1>;                 /* Maps to IRQ 72 */
            clocks = <&h2f_user0_clock>;
            altr,gpio-bank-width = <1>; /* embeddedsw.dts.params.altr,gpio-bank-width type NUMBER */
            altr,interrupt_type = <1>;  /* embeddedsw.dts.params.altr,interrupt_type type NUMBER */
            edge_type = <0>;    /* embeddedsw.dts.params.edge_type type NUMBER */
            level_trigger = <0>;    /* embeddedsw.dts.params.level_trigger type NUMBER */
            resetvalue = <0>;   /* embeddedsw.dts.params.resetvalue type NUMBER */
            #gpio-cells = <2>;
            gpio-controller;
        }; //end gpio@0x100000000 (pio_0)

        pio_1: gpio@0x100000010 {
            compatible = "altr,pio-14.1", "altr,pio-1.0";
            reg = <0x00000001 0x00000010 0x00000010>;
            interrupt-parent = <&hps_0_arm_gic_0>;
            interrupts = <0 41 1>;                    /* Maps to IRQ 73 */
            clocks = <&h2f_user0_clock>;
            altr,gpio-bank-width = <1>; /* embeddedsw.dts.params.altr,gpio-bank-width type NUMBER */
            altr,interrupt_type = <1>;  /* embeddedsw.dts.params.altr,interrupt_type type NUMBER */
            edge_type = <0>;    /* embeddedsw.dts.params.edge_type type NUMBER */
            level_trigger = <0>;    /* embeddedsw.dts.params.level_trigger type NUMBER */
            resetvalue = <0>;   /* embeddedsw.dts.params.resetvalue type NUMBER */
            #gpio-cells = <2>;
            gpio-controller;
        }; //end gpio@0x100000010 (pio_1)

        pio_2: gpio@0x100000020 {
            compatible = "altr,pio-14.1", "altr,pio-1.0";
            reg = <0x00000001 0x00000020 0x00000010>;
            interrupt-parent = <&hps_0_arm_gic_0>;
            interrupts = <0 42 1>;                    /* Maps to IRQ 74 */
            clocks = <&h2f_user0_clock>;
            altr,gpio-bank-width = <1>; /* embeddedsw.dts.params.altr,gpio-bank-width type NUMBER */
            altr,interrupt_type = <1>;  /* embeddedsw.dts.params.altr,interrupt_type type NUMBER */
            edge_type = <0>;    /* embeddedsw.dts.params.edge_type type NUMBER */
            level_trigger = <0>;    /* embeddedsw.dts.params.level_trigger type NUMBER */
            resetvalue = <0>;   /* embeddedsw.dts.params.resetvalue type NUMBER */
            #gpio-cells = <2>;
            gpio-controller;
        }; //end gpio@0x100000020 (pio_2)

The interrupt line "interrupts = <0 42 4>" Maps to 42 + 32 = 74.

Hope this helps Brian

dkapitel commented 9 years ago

Hi Brian, thanks for your help! After generating the dts i got this in the dts: user_input_device1_0: unknown@0x100010009 { compatible = "unknown,unknown-1.0"; reg = <0x00000001 0x00010009 0x00000001>; interrupt-parent = <&hps_arm_gic_0>; interrupts = <0 43 4>; clocks = <&clk>; }; //end unknown@0x100010009 (user_input_device1_0) so i changed it to: user_input_device1_0: uinput@0x100010009 { compatible = "altr,uinput-14.1", "altr,uinput-1.0"; reg = <0x00000001 0x00010009 0x00000001>; interrupt-parent = <&hps_arm_gic_0>; interrupts = <0 43 1>; clocks = <&clk>; }; //end unknown@0x100010009 (user_input_device1_0) After this i could load the fpga_uinput module and start the readstate from Howard. Unfortunately i dont get a reply after pushing a button. I also added these lines to the end of the dts: uinput@0xff210009{ compatible = "snps,dw-apb-uinput", "snps,dw-uinput-14.1", "snps,dw-uinput"; reg = <0xff210009 0x100>; interrupt-parent = <0x3>; interrupts = <0x0 0xc6 0x1>; clocks = <&clk>; }; But i still dont get a message after pushing a button. Now i am trying to find out if there happens an interrupt. Do you have any further ideas?

The tutorial you showed me said that if i change the dts/dtb like i did i should find something like "uinput@0x100010009" in my filesystem. Can you say me why i cant find this? Is it really bad that i cant find it?

Thanks Daniel

bstarck commented 9 years ago

Are you using a custom component in your QSys design? You could try using altera's pio component as a test and attach it to the required IRQ number. You may also need to rebuild the pre-loader.

dkapitel commented 9 years ago

Yes i want to use the interrupt verilog module from howard and his kernel module. I just got an interrupt from howards interrupt module. The altera pio component works well with IRQ, so i wanted to write my own QSYS component. Do you have an example from the dts with a custom QSYS component?