我正在通过从Linux移植以太网卡来实现RTEMS驱动。大部分工作已经完成,处理器IO模式工作正常,以及中断处理。现在我在实现DMA时遇到了问题。
具体地说,在我用作基础的Linux驱动程序中,使用了dma_alloc_coherent()函数。此函数将返回两个不同的地址:一个是驱动程序代码(主机CPU)将看到的地址,另一个是卡在DMA期间通过PCI访问相同内存区域的地址。
我在寻找合适的替换函数时遇到了问题。首先,我考虑使用pci_pci2cpu ()和pci_pci2cpu将这个地址转换为一个卡可以访问的地址,但是,malloc为IO返回0xFFFFFFFF,为其余两个模式返回0x0。
我考虑的第二种方法是使用双端口内存管理器,但我找不到使用它的有用示例。例如,rtems_port_create()函数需要提供指针*internal_start和*external_start,但是我不确定这个指针是从哪里开始的?
我使用的是Gaisler version4.11和Sparc架构(LEON3 cpu)。
最好的,伊凡
发布于 2016-04-25 20:56:36
好的,基本上我已经搞清楚了。
首先,RTEMS具有扁平内存模型,因此malloc()返回的地址是内存中的实际物理地址。这意味着我不需要dma_alloc_coherent(),因为malloc()已经在做同样的事情了。对于对齐内存,我使用了posix_memalign(),它也是受支持的。
其次,我需要看看卡和内存之间是否有任何地址转换。这与RTEMS无关,而是与系统架构有关,所以在查看GRLIB用户手册和查看grpci2内核的RTEMS初始化代码后,我发现没有内存转换(设置为1:1)。
底线是,如果我使用简单malloc分配缓冲区,并将地址提供给PCI卡,它将能够访问(读/写)这个缓冲区。
这些都是我一开始的假设,但最终我的问题出在有问题的DMA芯片上。:)
发布于 2016-02-29 05:14:52
我不确定我的问题是否正确,但不管怎样:
RTEMS不实现LEON系列DMA的处理程序。要使用DMA,您需要利用leon.h头文件中的LEON结构。该结构链接到LEON3处理器的内存地址。或者,您可以直接对寄存器进行寻址。
在此之后,您需要到http://www.gaisler.com/index.php/products/components/ut699下载UT699的功能手册(或搜索您正在使用的SoC :)
在这里,您将了解如何以正确的顺序编写注册表,以启动从PCI目标到PCI目标的DMA传输。
干杯
https://stackoverflow.com/questions/35171273
复制相似问题