11-25-2020 12:18 AM
11-25-2020 08:20 AM
Are you seeing a consistent lag, or does the delay vary from one interrupt to another?
There is inherent latency in delivering an interrupt via UIO to a userspace process. Most of this comes from process scheduling, which is strongly influenced by task priority and scheduler class. So if you have not already done so, consider adjusting the userspace program which does the poll() so that it runs under realtime scheduler class. You might also consider locking the program to a specific CPU core, and locking it in memory so it cannot get swapped out under memory pressure. As well, review any other high-priority processes, that might be preventing your task from running. Generally with this approach, it is possible to achieve latency well under a millisecond.
If you need even lower latency, you likely need to handle the interrupt in a kernel driver, rather than via UIO. This will remove the task scheduling variation, and your interrupt handler will run when the hardware interrupt occurs. You should be seeing latency in the microsecond range. At this point, there is a small difference between FIQ and normal interrupts, but here we are talking really small differences, not really worth the effort IMHO.
11-26-2020 02:13 AM
11-26-2020 05:55 AM
I see some minor issues in the code, but nothing that explains the 40msec delay. I would suggest that you check your PL logic that generates the 500ms interrupt. Most likely it is not running at the rate you expected. If possible, bring the signal out to a pin which you can probe using a scope.
Looking the output from "top", the CPUs are idle, and the load average is 0.0. So in this case, realtime scheduling and/or locking in memory will not have any noticeable effect.
In your code, you could make following minor changes:
1) Since there is only one event that you are waiting on, you can remove the poll() completely. Instead the read() will block until the interrupt occurs. This means one less system call, which will reduce latency slightly.
2) Remove the printf() right after the read(). Or move it later, after the send(). Again this will reduce latency slightly.
I would also recommend measuring timing on the Zynq system, rather than looking at received UDP packets on a different machine. One simple way is to run your mycodeth program using "strace -tt", this will show timestamps for each of the operations (write/poll/read/sendto). The strace "-T" option is also useful to measure time spent in each syscall.