-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
can vdma loop work ? #31
Comments
The answer to that is maybe. The driver has support for VDMA, but I was never able to get it to work even in a simple loopback mode. As discussed in #15, I believe this may actually be because of a lack of support in the backend Xilinx driver for DMA. However, that may have changed since then. In issue #25, it seems that someone may have gotten AXI VDMA to work. Perhaps @yaobaishen can comment on this? If you want some help debugging, can you send me your device tree entries for AXI VDMA. Also, can you send the output of |
thanks for your help, and i have emailed yaobaishen,but no reply.
/ { Using transmit channel 0 and receive channel 1. |
Sorry that I didn't work out VDMA either, so I am looking forward someone to verify it too. |
I will try working on it , yaobaishen reply me ,and he give up . thanks for you great work ! |
hei , I changed my hardwere desigin in vivado , maybe the vdma worked ? Z-turn# insmod axidma.ko Using transmit channel 0 and receive channel 1. random: fast init done DMA Timing Statistics: Why take it so long ? |
Interesting, well you're the first person to have VDMA working, so that's good. There must have been some issue with my design when I was testing. Hmm, the output of the timing statistics doesn't make much sense. According to the bandwidth numbers, your transfer should be completing in far less time, but it's not. So, for some reason the numbers are are inconsistent, which I haven't seen before. I do notice a line of output |
my bandwidth numbers is 24 , for RGB . |
I see, so the time is consistent. That's very odd though, because obviously 7.91 Mb / 27.71 s obviously does not come out to 285.42 Mb/s. The 285.42 Mb/s throughput number is about what I would expect, but the elapsed time is way too long. You haven't made any changes to the axidma benchmark code, correct? Sure thing, that's pretty straightforward. So you can just use Alternately, if you're planning on using Xilinx's DRM driver, you can use |
Oh one other thing I noticed is the following line:
This indicates that the kernel you're running on your board, and the one that you built the driver against do not match. This isn't the cause of the timing issue, but it can cause the driver to crash, so I'd recomment making sure you're using the kernel you built the driver against. |
I have seen the banchmark.c ,in " DMA Timing Statistics " function , Number of DMA Transfers is 1000 ,so 7.91Mb/27.71s *1000=285.42Mb/s. |
Sorry had a bit of a brain fart there, you're right about the time reported by the benchmark. What throughput are you expecting for the transfers? I know that my driver does introduce a bit of an overhead, but you should still get near the maximum performance. Looking at table 2-3 of the AXI VDMA User Guide, I think it's near the expected. Naturally, the exact throughput depends on data width configured in your AXI VDMA IP block. |
I see "axidma_video_transfer" function just use tx channel for display , on the contrary , I need datas streamed out from IP to DRAM buffer , not a loop , but a oneway road from external video signal to DRAM. I have not seen any “video_read” founction , maybe you can add |
Ahh I see. Actually, if you're just doing transfer one at a time, you can utilize Otherwise, I can send you a patch for continuous loop video read, analgous to |
Thank you so much , that's will be great helpful ! |
This was implemented as discussed in issue #31. The software stack now supports receive video transfers. This is a continuous receive transfer through VDMA, or a loop transfer. Transfers like this are useful for cameras or other video input devices that utilize frames. The call supports an arbitrary number of frame buffers. NOTE: This code is untested, and was only checked for correct compilation.
Ok, I added support with c3181d8. This code is currently untested, I only checked that it compiled against the most recent version of Xilinx's kernel. Unfortunatley, I don't have a device to test with, so could you run and test the code, and let me know if you run into any issues. |
vdma_test.txt I guess something wrong in memory of my app, segmentation fault. |
This was implemented as discussed in issue #31. The software stack now supports receive video transfers. This is a continuous receive transfer through VDMA, or a loop transfer. Transfers like this are useful for cameras or other video input devices that utilize frames. The call supports an arbitrary number of frame buffers. NOTE: This code is untested, and was only checked for correct compilation.
Yeah, even if there's an issue with your app's memory, it shouldn't cause a segfault in the kernel. I've pushed something new, so can you pull and try again. Also, can you post the output as a text file? It looks the formatting of it got messed up a bit. |
hei , I tried again . I changed your axidma_transfer.c , use |
Huh, that's really odd. I don't think I've seen any error like that before. The segfault from your logs seems to be pointing to the crash happening in the driver's video transfer function. However, even after combing over the funcntion, I can't find any obvious place where it would segfault. It's eve more odd that the two way transfer works perfectly fine for you. Just to confirm, you are on the latest version of the driver? |
Hi Brandon, I've just tried to use example axidma_display_image with a VDMA core and I get the same crash. Running the latest xilinx-linux on a ZC702 board. (PS. Thank you for this project; it's a lifesaver.) (Later: After some testing I've noticed that the error comes from accessing axidma_video_transaction.frame_buffer[0], which should point to the userspace address of the buffer. This is where the kernel faults; it seems that the specified address should be in kernel space. I've made a quick test and change void **frame_buffers, to void *frame_buffers, given that there is only one fb address and it runs without the crash). |
Oh got it, I think I might know what the issue is. I made a pretty simple mistake. In the IOCTL for AXIDMA_VIDEO_WRITE (and incidentally in the read IOCTL as well), I'm not copying the array of frame buffers from user space to kernel space, which is a big no-no. What is likely happening is that memory happens to be paged out, which leads to the segfault. The reason changing to So, I need a second call to |
sorry for later ,after long time debug , I cant get a complete frame picture use your vdma driver , so I begin my own driver use ioremap register of vdma ,and it easy to work . but it is not normative to linux kernel ,so I still want to try your driver , have you update the code ? |
Not yet, but I was planning on getting it up this weekend. I'll update this issue once it's up. |
I can confirm that this issue is caused by not calling My dirty fix for this was: --- a/driver/axidma_chrdev.c
+++ b/driver/axidma_chrdev.c
@@ -345,6 +345,7 @@
struct axidma_inout_transaction inout_trans;
struct axidma_video_transaction video_trans;
struct axidma_chan chan_info;
+ void *framebuffers[32];
// Coerce the arguement as a userspace pointer
arg_ptr = (void __user *)arg;
@@ -452,16 +453,13 @@
"AXIDMA_DMA_VIDEO_READ.\n");
return -EFAULT;
}
-
- // Verify that we can access the array of frame buffers
- size = video_trans.num_frame_buffers *
- sizeof(video_trans.frame_buffers[0]);
- if (!axidma_access_ok(video_trans.frame_buffers, size, true)) {
- axidma_err("Unable to copy frame buffer addresses from "
- "userspace for AXIDMA_DMA_VIDEO_WRITE.\n");
- return -EFAULT;
- }
-
+ if (copy_from_user(framebuffers, video_trans.frame_buffers,
+ video_trans.num_frame_buffers * sizeof(void*)) != 0) {
+ axidma_err("Unable to copy framebuffer pointers from userspace for "
+ "AXIDMA_DMA_VIDEO_READ.\n");
+ return -EFAULT;
+ }
+ video_trans.frame_buffers = framebuffers;
rc = axidma_video_transfer(dev, &video_trans, AXIDMA_READ);
break; There is a lot of room for improvement on this, however... Cheers P.S.: Thx for the nice piece of work. For simple interfacing with VDMA cores I however begin to think that the Xilinx driver makes it much much to complicated compared to the bare-metal way... |
Hello Brandon, ./axidma_benchmark -v AXI DMA Benchmark Parameters: Using transmit channel 0 and receive channel 1. DMA Timing Statistics: Next step will be to use a custom IP as axi stream source, I will also give the axidma_transfer a try. Please keep developing great software, your work is highly appreciated! |
@tangxu00 and @elektrokokke the most recent commit should resolve this issue. Let me know if you guys encounter any additional issues. |
@juergenmuc thanks, I appreciate it! Those numbers seem reasonable, though it's hard to say at a high-level glance. The smaller your transfer size, the less throughput you will see from the driver. This is because the system calls to initiate transfers have a relatively high overheard, so the larger the transfer, the more this cost will be amortized. |
use dma ip ,the driver,examples worked well, but vdma cant:
Z-turn# ./axidma_benchmark -v
AXI DMA Benchmark Parameters:
Transmit Buffer Size: 7.91 Mb
Receive Buffer Size: 7.91 Mb
Number of DMA Transfers: 1000 transfers
Using transmit channel 0 and receive channel 1.
axidma: axidma_dma.c: axidma_start_transfer: 298: VDMA receive transaction timed out.
Failed to perform the AXI DMA read-write transfer: Timer expired
how can i use vdma driver?
The text was updated successfully, but these errors were encountered: