• 0
HeroGian

Handling Interrupts with UIO Framework

Question

Posted (edited)

hello,

I'm trying to port a baremetal design, in which I have a simple HLS IP that performs vector additions, that triggers an interrupt when it finishes its computation. After the bitstream generation I exported the hdf and I generated the Petalinux project based on it, in which I specified "generic-uio" in the compatible field as follows:

amba_pl: amba_pl {
#address-cells = ;
#size-cells = ;
compatible = "simple-bus";
ranges ;
&irq_gen_0: irq_gen@43c00000 {
clock-names = "ap_clk";
clocks = ;
compatible = "generic-uio";
interrupt-names = "interrupt";
interrupt-parent = ;
interrupts = ;
reg = ;
xlnx,s-axi-axilites-addr-width = ;
xlnx,s-axi-axilites-data-width = ;
};
};


Then I created an appropriate bootargs configuration and placed inside the uEnv.txt file:

bootargs=console=ttyPS0,115200 earlyprintk uio_pdrv_genirq.of_id=generic-uio


and I enabled the following modules:

CONFIG_UIO=y
CONFIG_UIO_PDRV_GENIRQ=M
CONFIG_UIO_DMEM_GENIRQ=M
then I create a simple application that runs the initialization drivers of the IP and wait for interrupts:
int main() {
int a ;
int b ;
for(int i = 0; i < N; i) {
a = i;
b = i;
}
XIrq_gen HLSdevice;
XIrq_gen_Initialize(&HLSdevice, "irq_gen");
XIrq_gen_Write_a_Words(&HLSdevice, 0, a, N);
XIrq_gen_Write_b_Words(&HLSdevice, 0, b, N);
int uioFd = open(UIO_DEVICE, O_RDWR);
if( uioFd < 0) {
fprintf(stderr, "Cannot open %s: %s
", UIO_DEVICE, strerror(errno));
return -1;
}
volatile uint32_t* counters = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_SHARED, uioFd, 0);
if(counters == MAP_FAILED) {
fprintf(stderr, "Cannot mmap: %s
", strerror(errno));
close(uioFd);
return -1;
}
uint32_t intInfo;
ssize_t readSize;
for(int i = 0; i < 10; i) {
XIrq_gen_Start(&HLSdevice);
printf("XIrq_gen_Start()
");
intInfo = 1;
if(write(uioFd, &intInfo, sizeof(intInfo)) < 0) {
fprintf(stderr, "Cannot acknowledge uio device interrupt: %s
", strerror(errno));
break;
}
printf("write()
");
// Wait for interrupt
readSize = read(uioFd, &intInfo, sizeof(intInfo));
if(readSize < 0) {
fprintf(stderr, "Cannot wait for uio device interrupt: %s
", strerror(errno));
break;
}
// Display counter value
printf("We got %lu interrupts, counter value: 0xx
", intInfo, counters );
}
XIrq_gen_Release(&HLSdevice);
return 0;
}


 
The program blocks on the read call and does not receive any interrupts. Under /proc/interrupts I can see my HLS IP, but the interrupt counter is still zero:
 

root@InterruptLinux:~# cat /proc/interrupts 
CPU0 CPU1 
16: 1 0 GIC-0 27 Edge gt
17: 0 0 GIC-0 43 Level ttc_clockevent
18: 2998 **** GIC-0 29 Edge twd
19: 0 0 GIC-0 37 Level arm-pmu
20: 0 0 GIC-0 38 Level arm-pmu
21: 43 0 GIC-0 39 Level f8007100.adc
24: 0 0 GIC-0 35 Level f800c000.ocmc
25: 726 0 GIC-0 82 Level xuartps
26: 11 0 GIC-0 51 Level e000d000.spi
27: 534 0 GIC-0 54 Level eth0
28: 248 0 GIC-0 56 Level mmc0
29: 0 0 GIC-0 45 Level f8003000.dmac
30: 0 0 GIC-0 46 Level f8003000.dmac
31: 0 0 GIC-0 47 Level f8003000.dmac
32: 0 0 GIC-0 48 Level f8003000.dmac
33: 0 0 GIC-0 49 Level f8003000.dmac
34: 0 0 GIC-0 72 Level f8003000.dmac
35: 0 0 GIC-0 73 Level f8003000.dmac
36: 0 0 GIC-0 74 Level f8003000.dmac
37: 0 0 GIC-0 75 Level f8003000.dmac
38: 0 0 GIC-0 40 Level f8007000.devcfg
45: 0 0 GIC-0 41 Edge f8005000.watchdog
46: 0 0 GIC-0 61 Level irq_gen
IPI1: 0 0 Timer broadcast interrupts
IPI2: 844 1294 Rescheduling interrupts
IPI3: 1 2 Function call interrupts
IPI4: 0 0 CPU stop interrupts
IPI5: 0 0 IRQ work interrupts
IPI6: 0 0 completion interrupts
Err: 0


could you please give me some hints? thanks

Edited by JColvin
created code blocks for readability

Share this post


Link to post
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Hi @HeroGian,

I've replicated your issue with my own setup and am getting an idea for a solution. I've got a few questions that I'd like to ask to help me get closer. First, what version of Petalinux are you using? What file are device tree file are you editing? In the device tree fragment you provided, I noticed that there are a few parameters left empty, such as interrupt-parent, interrupts, etc. Have these been intentionally left blank? Lastly, I'm unfamiliar with any of the XIrq_gen function calls that you are making within your application code. Is that part of the source generated for your HLS IP?

Looking forward to helping you reach a working solution,
AndrewHolzer

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now