NI Linux Real-Time Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt Latency

Hello all,

 

My company has looked at the sbRIO product line several times (first with the 9606, then the 9607) but found we couldn't use these products due to FPGA size limitations. With the new 9608/9 products and larger FPGAs we're looking at sbRIO again, but are also looking at alternative ways of using the sbRIO. Instead of trying to put all of the fast control loops in the FPGA we are considering running some of the floating point control algorithms on the cpu to avoid bloating the FPGA. To do this effectively we typically use an FPGA interrupt to signal the cpu when data is available to run the control algorithms.

 

Using our own hardware (Freescale ARM Dual core 1GHz + Linux + Xenomai) we see latencies <3us when running a real control loop interrupt at 20kHz. So the question is can we get similar results using sbRIO?

 

Right now we don't have sbRIO-9608/9 hardware in house so we are using the sbRIO-9607 for testing. Just for fun we took a Zynq-7020 development board (not an sbRIO, but using the same Zynq-7020 as the 9607) and wrote a bare-metal application triggered by an FPGA interrupt using Xilinx tools and measured <1us of latency. We also ran the interrupt well beyond 50kHz ==> so this is technically feasible! But we also expect to see higher latency with sbRIO due to the scheduler in Linux-RT.

Switching to sbRIO-9607, we have only tested a user-mode interrupt handler at the moment. This benchmark used 2 pieces: a LabVIEW FPGA VI that generates an interrupt every X ms using a timer, and a C application that uses the CAPI to wait/acknowledge the interrupt and measure time between interrupts. Using this approach we measured +/-60us of latency when servicing a 10kHz interrupt - much higher than I expected.

 

We are currently working on a kernel-mode interrupt handler (device driver) which will hopefully improve the interrupt latency, but in the meantime I thought maybe some else has gone down this road and might have some insight? Specific questions below:

 

1) Does NI have any benchmarks for interrupt latency across the RIO product line? I'm especially curious in differences between the ARM and Intel-based RIO products. Can we expect lower interrupt latency on the 9608/9 products compared to the 9607?

 

2) Is 60us (peak) latency expected for a user-mode interrupt handler on Linux-RT and sbRIO-9607? We are more familiar with Xenomai and haven't used PREEMPT-RT kernels before, but I assumed the performance would be similar. (Also curious what NI is using under the hood, do LabVIEW FPGA interrupts use FIQ on the ARM platforms?)

 

3) Any tips or ticks for lowering interrupt latency on these products?

 

4) Does NI offer any way to configure the sbRIO for AMP mode instead of SMP? Eg a bare metal application on 1 core that handles fast FPGA interrupts, and Linux-RT on the 2nd core (instead of Linux-RT on both cores).

 

Thanks!

0 Kudos
Message 1 of 2
(2,892 Views)

After more digging it appears I was comparing kernel-mode interrupt latency to user-mode which isn't a fair comparison. On our Freescale Arm+Linux+Xenomai platform we do see closer to 60us latency with user-mode interrupts (similar to the performance on Linux-RT with sbRIO). This is a great sign - it suggests if we can get a kernel-mode interrupt handler running on sbRIO we should significantly lower the interrupt latency, which would allow us to use sbRIO for these applications.

 

But I've stalled out while setting up this test. I have the cross compile toolchain and kernel sources configured to the point that I can compile and install a kernel module on the sbRIO-9607 without issue. But hooking the interrupt is the next challenge. It appears that when LabVIEW FPGA triggers interrupt 0 (value of 0 passed to the LabVIEW FPGA Interrupt VI) it is mapped to IRQ 61 on the CPU - this makes sense when looking at Zynq-7020 documentation. However this interrupt has already been assigned to an NI kernel driver named atomiczynqk.

 

Luckily IRQ61 has been assigned as a shared interrupt (IRQF_SHARED), which should allow it to trigger both atomiczynqk and the test kernel module that I'm building for this benchmark. But after installing the test module, IRQ61 is no longer triggered (when viewed in /proc/interrupts). The test module is acquiring the interrupt via request_irq():

 

// request IRQ 61
status = request_irq(61, &irq_handler, IRQF_NO_SOFTIRQ_CALL | IRQF_EARLY_RESUME | IRQF_SHARED, MODULE_NAME, (void *)&dev_id);

 

Maybe someone with better knowledge of the atomiczynqk module can chime in here and point out what I'm doing wrong.

0 Kudos
Message 2 of 2
(2,810 Views)