我需要与基于AXI突发接口的FPGA器件通信。在不涉及DMA的情况下,通过Linux访问此类设备有哪些方法? Burst是AXI标准的固有属性,通常应在传输大量数据时自动触发。更大的问题是FPGA的设计只能响应AXI总线上的突发类型请求。因此,当应用程序尝试顺序复制时,这会在Linux上导致严重问题。我已经尝试memcpy
但它不起作用。
答案 0 :(得分:3)
我假设你的“FPGA器件”是一个自定义模块,通过AXI接口内存映射到Cortex-A9。我认为有两种或三种方法可以使这项工作。
1)可缓存映射。高速缓存硬件接口一次执行整个高速缓存行的突发传输。您需要手动清理(写入后)并使其无效(在读取之前)。
2)不可缓存的映射,并且ARM汇编语言例程处理低级传输。我认为“加载和存储多个寄存器”指令可以提供您正在寻找的内容。
我遇到类似的问题,需要使用Cortex-A9处理器的8字节传输来访问AXI外设(自定义内存控制器)。当然,通常的ARM指令传输1,2或4个字节(字节,半字,字)。那些通过可缓存映射工作,但不是通过不可缓存的映射。 LDM/STM,一次2个字,与两个映射一起使用。
当然,AHB / AXI传输模式取决于实现方式。根据您的描述,您需要INCR或WRAP模式而不是SINGLE。但它不应该那样。这提出了第三种方法:3)与您的数字硬件设计师交谈,让他了解其实施对软件的影响。
在我看来,您不必进行异常/自定义低级MMU操作。 Linux有高级方法,您可以在设备驱动程序和/或board.c中放置标准挂钩,主要选项是是否要进行未缓存(即COHERENT)。请参阅LDD3。
答案 1 :(得分:1)
您需要设置MMU以通知硬件组件的功能。您还需要确保整个互连支持突发并且不进行任何转换(如果在生成互连时组件的功能存在任何歧义,则可能会发生这种情况。)
要设置MMU,您可以执行以下调用:
/* shareable device: S=b0 TEX=b000 AP=b11, C=b0, B=b1 = 0xC06*/
Xil_SetTlbAttributes(COMPONENT_BASE_ADDRESS, 0xC06);
属性定义如下(来自Zynq Technical Reference Manual):
Encoding Bits Cache Attribute
C B
0 0 Non-cacheable
0 1 Write-back, write-allocate
1 0 Write-through, no write-allocate
1 1 Write-back, no write-allocate
因此上面的行会将区域设置为回写,写入分配,可以在写入时为您提供突发访问权。