完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我正在尝试在zc706板上获得一个基本的示例应用程序,以显示它是否值得使用Zynq用于我们的应用程序,但是我无法获得标准功能。
我正在寻找一个旨在与FMC卡接口的参考硬件设计,我正在尝试做的是添加一个可以从Zynq上运行的Linux控制的额外IP。 我要做的就是将一些配置数据写入PL中的BRAM。 要做到这一点,根据我在其他地方得到的建议,我提出了一个axi_cdma。 所以CDMA有一个S_AXI_LITE端口,连接到AXI_INTERCONNECT上的M08_AXI,然后转到PS-7上的GP0。 它还有一个M_AXI端口,它连接到AXI_INTERCONNECT的S00_AXI。 该互连具有M00_AXI,它连接到AXI_BRAM控制器。 它还有M01_AXI,它转到S_AXI_HP3。 AXI_BRAM控制器进入BLOCK MEMORY GENERATOR。 我想要做的就是在Linux中向DMA引擎提交一个事务,并将我提交的缓冲区中的数据写入块存储器生成器创建的BRAM中。 据我所知,我上面描述的设置应该允许这样做。 在我的地址编辑器中,在sys_ps7下,有一个AXI_CDMA_0条目,其偏移地址为0x43C0_0000,范围为64K。 在AXI_CDMA_0(sys_ps7的单独条目)下,有两个条目AXI_BRAM_CTRL_0,偏移量为0xC000_0000,范围为4K,sys_ps7,偏移量为0x0000_0000,范围为1G。 现在HSI不适合我,所以我不得不尝试自己填写一个条目。 我做了: axibram @ 43C00000 { #address-cells =; #size-cells =; #dma-cells =; compatible =“cmp,axi-bram-ctrl-1.00”; reg =; 中断=; interrupt-parent =; dma-channel @ 43C00000 { buswidth =; }; }; 我不确定这是否正确,但似乎有些错误,因为我觉得它不起作用。 我看到的问题是 1. DMA事务每次都超时。 但是,我在测试中输入了一个读取命令,看起来我正在尝试编写的数据将被写入内存。 问题是我不知道在哪里。 我不能使用hexdump -C因为如果我使用-s用于超过2FFF0000的任何东西我会得到一个糟糕的地址失败。 但无论如何,DMA引擎从未承认传输已完成? 2.据我所知,没有数据写入BRAM。 我的第一个想法是,我可能会将错误的地址放入设备树中,因为我不知道43c00000是否是正确的使用方式。 如果有一个工具可以让我看到在执行过程中写入BRAM的数据,那会有所帮助 请帮忙,我一直试图解决这个问题 以上来自于谷歌翻译 以下为原文 I'm trying to get a basic example application going on the zc706 board to show whether or not its worth using the Zynq for our application, but I'm having trouble getting standard functionality going. I am looking at a reference hardware design intended to interface with an FMC card, and what I'm trying to do is add an additional IP that can be controlled from Linux running on the Zynq. All I'm trying to do is write some configuration data to a BRAM in PL. To do this, based on the recommendations I've gotten elsewhere, I put in an axi_cdma. So the CDMA has an S_AXI_LITE port that goes to M08_AXI on the AXI_INTERCONNECT which goes to GP0 on the PS-7. It also has a M_AXI port which goes to S00_AXI of an AXI_INTERCONNECT. That interconnect has M00_AXI, which goes to an AXI_BRAM CONTROLLER. It also has M01_AXI, which goes to S_AXI_HP3. The AXI_BRAM CONTROLLER goes to a BLOCK MEMORY GENERATOR. What I want to be able to do with this is submit a transaction to the DMA engine in Linux, and have the data in the buffer that I submit be written to the BRAM created by the block memory generator. As far as I understand it, the setup I described above should allow this. In my Address Editor, under sys_ps7, there is an AXI_CDMA_0 entry, which has an offset address of 0x43C0_0000 and range of 64K. under AXI_CDMA_0, a separate entry from sys_ps7, there are two entries, AXI_BRAM_CTRL_0, with an offset of 0xC000_0000 and a range of 4K, and sys_ps7, with an offset of 0x0000_0000 and a range of 1G. Now HSI isn't working for me, so I had to try making an entry myself. I did: axibram@43C00000{ #address-cells = <0x1>; #size-cells = <0x1>; #dma-cells = <0x1>; compatible = "cmp,axi-bram-ctrl-1.00"; reg = <0x43C00000 0x1000>; interrupts = <0x0 0x37 0x4>; interrupt-parent = <0x1>; dma-channel@43C00000 { buswidth = <0x20>; }; }; Which I am not sure if that is correct or not, but something seems to be wrong as I don't think it is working. The problem I am seeing is that 1. The DMA transaction times out every time. However, I put in a read comand in my test, and it looks like the data I am trying to write DOES get written into memory somewhere. The problem is I don't know where. I can't use hexdump -C because if I use a -s for anything past 2FFF0000 I get a bad address failure. But regardless, DMA engine never acknowledges that a transfer is finished? 2. As far as I can tell there is no data being written to the BRAM. My first thought is that maybe I put the wrong address into the device tree, becasue I dont know if 43c00000 was the right one to use. It would help if there was a tool that would actually let me see what the data written in the BRAM was during execution Please help, I've been trying to figure this out for a while |
|
相关推荐
15个回答
|
|
设备树中的地址仅供参考。
您需要将bram的地址编程到CDMA目标地址寄存器中。 除了计数/长度之外,您还需要编程CDMA的源地址寄存器。 - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 the address in the device tree is only informative. You need to program address of the bram into the CDMA destination address register. Also you need to program the CDMA's source address register in addition to a count/length.- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
是的,但这不是条目的作用吗?
那应该是我现在的条目所涵盖的吗? 以上来自于谷歌翻译 以下为原文 Right, but isn't that what the |
|
|
|
>>对,但这不是条目的作用吗?
那应该是我现在的条目所涵盖的吗? 不,该条目不会导致地址reg被编程。 你必须编程源和&amp; 目的地自己解决。 - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 >> Right, but isn't that what the No, that entry doesn't cause the address reg to be programmed. You have to program source & destination addresses yourself.- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
那怎么回事呢?
根据我的理解,DMA引擎API没有特别定义通道的寻址,至少在我看到的例子中。 所以我认为它正在从设备中检索这些信息。 你怎么能告诉它地址? 以上来自于谷歌翻译 以下为原文 So how does that work exactly? From what I understood the DMA Engine API doesn't specifically have you define the addressing for the channel, at least in the example I saw. So I assumed that it was retreiving that information from the devicetree. How are you supposed to tell it the addresses? |
|
|
|
http://www.xilinx.com/support/documentation/ip_documentation/axi_cdma/v4_1/pg034-axi-cdma.pdfpage 13,寄存器0x18和0x20。
- 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 http://www.xilinx.com/support/documentation/ip_documentation/axi_cdma/v4_1/pg034-axi-cdma.pdf page 13, register 0x18 and 0x20.- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
对,我明白了。
但是正如我所提到的,我试图弄清楚它是如何使用Linux的。 我无法直接访问与这些寄存器映射相对应的内存空间,所以我不能只写那里。 我想,Linux DMA引擎处理写入这些寄存器的细节,我不能手动完成。 以上来自于谷歌翻译 以下为原文 Right, I understand that much. However as I mentioned, I am trying to figure out how this works using Linux. I can't directly access the memory space corresponding to those register mappings, so I can't just write there. The Linux DMA Engine, I imagine, handles the specifics of writing to those registers, I can't do it manually. |
|
|
|
从技术上讲,你可以。
你可以mmap cdma地址,它给你一个你可以使用的虚拟地址。 你也可以获得你拥有的任何内存的物理地址,并将它们编程到cdma寄存器中,但你是对的,你不必这样做,linux cdma驱动程序为你处理所有这些。 - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 technically you can. you can mmap the cdma address which gives you a virtual address you can use. you can also get physical addresses for any memory you have and program them into the cdma registers but you are right you don't have to do this and the linux cdma driver handles all of these for you.- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
好吧我会记住这一点。
但是我更喜欢通过CDMA驱动程序来实现,因为这似乎是更“适当”的做事方式。 因此,在仅使用DMA引擎而不是mmapping的情况下,驱动程序如何获取有关这些地址的信息? 我的想法是驱动程序读取在devicetree中写入的地址以了解起始地址的位置,并且本身就知道寄存器映射的偏移量。 但是,在设备树中只有一个条目reg =。 这解释了GP0端口应该写入的位置,以便到达CDMA上的控制寄存器,就像我想写入源地址一样,我会写入0x18,这意味着写入0x43000018。 但是,我认为DESTINATION地址是0xC0000000,因为那是BRAM控制器的CDMA映射。 如何告诉设备树该地址,以便它知道我要将数据传输到哪里? 以上来自于谷歌翻译 以下为原文 Alright Ill keep that in mind. However I'd prefer to do it through the CDMA driver since that seems to be the more "proper" way of doing things. So in the case of just using the DMA Engine rather than mmapping, how does the driver get information on these addresses? My thought was that the driver reads the addressses which are written in the devicetree to know where the start addresses are, and just inherently knows the offsets for the register mappings. However, in the device tree there is only an entry reg = <0x43000000 0x1000>. That explains where the GP0 port should write to in order to get to the control registers on the CDMA, like when I want to write the source address I would write to 0x18, so that means writing to 0x43000018. But the DESTINATION address would be, I think, 0xC0000000, because thats the CDMA mapping for the BRAM controller. How do I tell the device tree that address, so it knows where I'm trying to transfer data to? |
|
|
|
正确的方法是开发一个新的内核驱动程序,它导出一个用户级api来分配内存,并使用linux dma驱动程序的内核api启动,编程&amp;
处理中断等。设备中的所有地址都是物理地址,它们需要映射到试图与它们通信的处理器的地址空间。 内核驱动程序管理这些交互。 - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 the proper way is to develop a new kernel driver which exports a user-level api to allocate memory and also use the linux dma driver's kernel api to start, program & handle the interrupts etc. All the addresses in the devicetree are physical address and they need to be mapped to the address space of the processor which is trying to talk to them. The kernel drivers manage these interactions.- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
这是我不太明白的后半部分,“使用linux dma驱动程序的内核api启动,编程和处理中断等”
在我在这个论坛上找到的例子中似乎没有任何用于手动设置这些内容的规定。 该示例只是找到适当的DMA通道并提交事务,这似乎表明Engine正在从内核模块外部获取有关寻址和中断处理的特定信息 以上来自于谷歌翻译 以下为原文 It's the latter part of that I don't quite understand, "use the linux dma driver's kernel api to start, program & handle the interrupts etc" In the example I found on this forum there doesn't seem to be any provision used for setting these things manually. The example simply locates the appropriate DMA channel and submits the transaction, which seems to indicate that the Engine is getting the specific information on addressing and interrupt handling from outside the kernel module |
|
|
|
>>提交事务交易是什么样的?
不知道你发现的例子是什么,很难评论更多。 - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 >> submits the transaction what does the transaction look like? without knowing what the example you found does, it's difficult to comment much more.- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
我正在看这个帖子上发布的例子:
https://forums.xilinx.com/t5/Embedded-Linux/AXI-DMA-with-Zynq-Running-Linux/td-p/522755 在第二篇文章中:axidma.c.golden。 如您所见,驱动程序本身未指定地址 以上来自于谷歌翻译 以下为原文 I am looking at the example posted on this thread: https://forums.xilinx.com/t5/Embedded-Linux/AXI-DMA-with-Zynq-Running-Linux/td-p/522755 in the second post: axidma.c.golden. As you can see no addresses are specified in the driver itself |
|
|
|
>>如您所见,驱动程序本身未指定地址
你看的不够仔细。 看看src_dma_buffer是如何赋予tx_dma_handle的,它被赋予tx_cookie,它被赋予toaxidma_start_transfer。 这是一个内核驱动程序,因此不涉及用户空间缓冲区,但src_dma_buffer等的地址将传递给下游内核驱动程序以进行所需的事务。 如果要将此驱动程序中的服务导出到用户空间,则需要找到一种进行传输的方法(即将用户空间地址映射到“src_dma_buffer”等)。 for(i = 0; i device-> dev,src_dma_buffer,dma_length,DMA_TO_DEVICE); rx_dma_handle = dma_map_single(rx_chan-> device-> dev,dest_dma_buffer,dma_length,DMA_FROM_DEVICE); / *准备DMA缓冲区和要执行的DMA事务,并确保没有 *任何错误 * / rx_cookie = axidma_prep_buffer(rx_chan,rx_dma_handle,dma_length,DMA_DEV_TO_MEM,&amp; rx_cmp); tx_cookie = axidma_prep_buffer(tx_chan,tx_dma_handle,dma_length,DMA_MEM_TO_DEV,&amp; tx_cmp); if(dma_submit_error(rx_cookie)|| dma_submit_error(tx_cookie)){ printk(KERN_ERR“xdma_prep_buffer error n”); 返回; } printk(KERN_INFO“正在启动DMA传输 n”); / *启动两次DMA传输并等待它们完成 * / axidma_start_transfer(rx_chan,&amp; rx_cmp,rx_cookie,NO_WAIT); axidma_start_transfer(tx_chan,&amp; tx_cmp,tx_cookie,WAIT); - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 >> As you can see no addresses are specified in the driver itself You are not looking carefully enough. See how src_dma_buffer is given to tx_dma_handle, which is given to tx_cookie which is given to axidma_start_transfer. This is a kernel driver so no user space buffer is involved but the addresses of the src_dma_buffer etc is passed to the downstream kernel driver for the desired transaction. If you want to export services from this driver to user space, you need to find a way to do the transfer (ie map user space addresses to "src_dma_buffer" etc.). for (i = 0; i < dma_length; i++) src_dma_buffer = i; /* Step 4, since the CPU is done with the buffers, transfer ownership to the DMA and don't * touch the buffers til the DMA is done, transferring ownership may involve cache operations */ tx_dma_handle = dma_map_single(tx_chan->device->dev, src_dma_buffer, dma_length, DMA_TO_DEVICE); rx_dma_handle = dma_map_single(rx_chan->device->dev, dest_dma_buffer, dma_length, DMA_FROM_DEVICE); /* Prepare the DMA buffers and the DMA transactions to be performed and make sure there was not * any errors */ rx_cookie = axidma_prep_buffer(rx_chan, rx_dma_handle, dma_length, DMA_DEV_TO_MEM, &rx_cmp); tx_cookie = axidma_prep_buffer(tx_chan, tx_dma_handle, dma_length, DMA_MEM_TO_DEV, &tx_cmp); if (dma_submit_error(rx_cookie) || dma_submit_error(tx_cookie)) { printk(KERN_ERR "xdma_prep_buffer errorn"); return; } printk(KERN_INFO "Starting DMA transfersn"); /* Start both DMA transfers and wait for them to complete */ axidma_start_transfer(rx_chan, &rx_cmp, rx_cookie, NO_WAIT); axidma_start_transfer(tx_chan, &tx_cmp, tx_cookie, WAIT);- Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
我不知道我是否已经解释了我正确理解的问题。
我对如何通过Userspace访问此内核模块没有任何问题。 我知道怎么做到这一点。 但两个交易所描述的 tx_dma_handle = dma_map_single(tx_chan-> device-> dev,src_dma_buffer,dma_length,DMA_TO_DEVICE); 和 rx_dma_handle = dma_map_single(rx_chan-> device-> dev,dest_dma_buffer,dma_length,DMA_FROM_DEVICE); 都是单向的。 “dma_map_single”函数将指向每个缓冲区的指针分配给tx_chan和rx_chan结构的“device”子结构。 但这两者都只定义了DMA传输的一端。 对于tx_dma_handle,数据在哪里? 在rx_dma_handle中,数据来自哪里? 我知道我想从哪里来,但这不是dma_map_single函数的一部分。 它说的全部是TO或FROM DEVICE,但是定义在哪里? 我试图弄清楚我可以在哪里修改设置“DEVICE”的定义,或者DMA事务的另一端的位置。 以上来自于谷歌翻译 以下为原文 I don't know if I've explained what I'm having an issue understanding properly. I don't have any problem with how to make this kernel module accessible through Userspace. I know how I can do that. But both of the transactions described by tx_dma_handle = dma_map_single(tx_chan->device->dev, src_dma_buffer, dma_length, DMA_TO_DEVICE); and rx_dma_handle = dma_map_single(rx_chan->device->dev, dest_dma_buffer, dma_length, DMA_FROM_DEVICE); are both one way. The "dma_map_single" function assigns the pointer to each of those buffers to the "device" substructure of the tx_chan and rx_chan structs. But both of those are only defining one end of that DMA transfer. For tx_dma_handle, where is the data going? in rx_dma_handle, where is the data coming from? I know where I WANT it to come from, but that's not a part of the dma_map_single function. All it says is TO or FROM DEVICE, but where is that defined? I'm trying to figure out where I can modify where the definition of where "DEVICE" is set, or where the other end of this DMA transaction is going to be. |
|
|
|
人们需要看看人们在看什么。
事务都是单向的,因为你的例子是AXI DMA,它是axi-stream和axi-stream到内存DMA的内存,所以没有地址用于传输目的地(因为它产生一个流)并且没有 接收源的地址(因为它来自流)。 在示例框图中,您可以看到传输流被环回以接收流,因此事务实际上从发送源地址到接收目标地址都被编程。 另一方面,AXI CDMA是存储器到存储器DMA控制器,因此每个通道都有一个源地址和一个目标地址。 一个合适的例子在这里:https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/cdmatest.c - 如果提供的信息有用,请将答案标记为“接受为解决方案”。给予您认为有用且回复的帖子。 以上来自于谷歌翻译 以下为原文 One needs to see what one is looking at. The transactions are both one way because the example you have is for AXI DMA which is a memory to axi-stream and axi-stream to memory DMA so there is no address for the transmit destination (as it produces a stream) and there is no address for receive source (as it comes from a stream). In the example block diagram you see the transmit stream is looped back to receive stream so the transactions actually become from transmit source address to receive destination address both of which are programmed. AXI CDMA on the other hand is a memory to memory DMA controller so each channel has a source address and a destination address. A suitable example is here: https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/cdmatest.c - Please mark the Answer as "Accept as solution" if information provided is helpful. Give Kudos to a post which you think is helpful and reply oriented. |
|
|
|
只有小组成员才能发言,加入小组>>
2385 浏览 7 评论
2800 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2264 浏览 9 评论
3336 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2433 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
759浏览 1评论
请问vc707的电源线是如何连接的,我这边可能出现了缺失元件的情况导致无法供电
548浏览 1评论
求一块XILINX开发板KC705,VC707,KC105和KCU1500
371浏览 1评论
1966浏览 0评论
685浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 04:16 , Processed in 1.504528 second(s), Total 106, Slave 90 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号