简体   繁体   English

任何用于AXI突发类型设备的内置Linux方法?

[英]Any built-in Linux methods for AXI-burst type devices?

I need to communicate with an FPGA device based on an AXI-burst interface. 我需要与基于AXI突发接口的FPGA器件进行通信。 What are the ways to access such a device through Linux without involving a DMA? 在不涉及DMA的情况下,通过Linux访问此类设备有哪些方法? Burst is an intrinsic property of the AXI standard, which should typically be triggered automatically when large amounts of data are being transferred. Burst是AXI标准的固有属性,通常应在传输大量数据时自动触发。 And the bigger problem is the FPGA is designed so as to respond only to burst-type requests over the AXI bus. 更大的问题是FPGA的设计只能响应A​​XI总线上的突发类型请求。 So this causes serious issues on Linux when the application tries sequential copy. 因此,当应用程序尝试顺序复制时,这会在Linux上导致严重问题。 I have already tried memcpy and it doesn't work. 我已经尝试过memcpy而且它不起作用。

I assume your “FPGA device” is a custom block, memory-mapped over AXI interface to Cortex-A9. 我假设你的“FPGA器件”是一个自定义模块,通过AXI接口内存映射到Cortex-A9。 I think there are 2 or 3 ways you could make this work. 我认为有两种或三种方法可以完成这项工作。

1) Cacheable mapping. 1)可缓存映射。 Cache hardware interface does burst-transfer of an entire cache line at a time. 高速缓存硬件接口一次执行整个高速缓存行的突发传输。 You would need to manually clean (after writes) and invalidate (before reads). 您需要手动清理(写入后)并使其无效(在读取之前)。

2) Non-cacheable mapping, and have an ARM assembly language routine handle the low-level transfer. 2)不可缓存的映射,并且具有ARM汇编语言例程来处理低级传输。 I think the “Load and Store Multiple registers” instructions can provide what you are looking for. 我认为“加载和存储多个寄存器”指令可以提供您正在寻找的内容。

I had a similar problem where an AXI peripheral (custom memory controller) needed to be accessed with 8-byte transfers from Cortex-A9 processor. 我有一个类似的问题,需要通过Cortex-A9处理器的8字节传输来访问AXI外设(自定义内存控制器)。 The usual ARM instructions, of course, transfer 1, 2, or 4 bytes (byte, halfword, word). 当然,通常的ARM指令传输1,2或4个字节(字节,半字,字)。 Those worked through cacheable mapping, but not through non-cacheable mapping. 那些通过可缓存映射工作,但不是通过不可缓存的映射。 LDM/STM , 2 words at a time, worked with both mappings. LDM / STM ,一次2个字,与两个映射一起使用。

AHB/AXI transfer modes are implementation dependent, of course. 当然,AHB / AXI传输模式取决于实现方式。 Per your description, you need INCR or WRAP modes rather than SINGLE. 根据您的描述,您需要INCR或WRAP模式而不是SINGLE。 But it should not have to be that way. 但它不应该那样。 That brings up the third way you could make this work: 这提出了你可以做到这一点的第三种方式:

3) Talk with your digital hardware designer, make him aware of the software impact of his implementation. 3)与您的数字硬件设计师交谈,让他了解其实施对软件的影响。

In my opinion, you shouldn't have to do unusual / custom low-level MMU operations. 在我看来,你不应该做不寻常/定制的低级别MMU操作。 Linux has high-level methods, you would put standard hooks in your device driver and/or board.c, the main option is whether to go uncached (ie COHERENT). Linux有高级方法,您可以在设备驱动程序和/或board.c中放置标准挂钩,主要选项是是否要进行非缓存(即COHERENT)。 Refer to LDD3 . 请参阅LDD3

You need to set up the MMU to inform the hardware of the capabilities of your component. 您需要设置MMU以通知硬件组件的功能。 You also need to ensure that the entire interconnect supports bursts and isn't doing any conversions (which can happen if there's any ambiguity about your component's capabilities when the interconnect is generated). 您还需要确保整个互连支持突发并且不进行任何转换(如果在生成互连时组件的功能存在任何歧义,则可能会发生这种情况)。

To set up the MMU you perform a call like this: 要设置MMU,您可以执行如下调用:

/* shareable device: S=b0 TEX=b000 AP=b11, C=b0, B=b1 = 0xC06*/
Xil_SetTlbAttributes(COMPONENT_BASE_ADDRESS, 0xC06);

attributes are defined as follows (from Zynq Technical Reference Manual ): 属性定义如下(来自Zynq技术参考手册 ):

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

So the above line would set the region to write-back, write allocate, which may give you burst access on write. 所以上面的行会将区域设置为回写,写入分配,这可能会给你写入突发访问权限。

See also Xilinx AR#47406 and this forum post . 另见Xilinx AR#47406此论坛帖子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM