Zynq PetaLinux 系统 PL 需要写入 PS RAM - 如何为 PL 提供正确的物理地址?

问题描述 投票:0回答:1

我有一个 Zynq 系统,其中 PL 中的逻辑生成需要写入 PS RAM 的大数据块。在我天真的想法中,我会使用

new
malloc()
来获取指向已分配内存的指针,然后将该指针虚拟地址转换为物理地址。

这有几个问题。一是内存在被我的应用程序写入之前可能不存在。另一个是物理地址可能会改变。可能还有其他原因。

显然,PL 希望始终写入同一个位置并期望内存存在!

这是我尝试过的(C++):

size_t length_in_bytes = 4096*8;
uint8_t * memBlockPtr;
const size_t page_boundary = 4096;
int retval = posix_memalign(reinterpret_cast<void**>(&memBlockPtr), page_boundary, length_in_bytes);
if (retval != 0)
{
    perror("posix_memalign");
    exit(1);
}

uint8_t * physAddr = nullptr;
physAddr = reinterpret_cast<uint8_t *>(mmap(reinterpret_cast<void*>(memBlockPtr),
                length_in_bytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, -1, 0));
if (physAddr == MAP_FAILED)
{
    perror("mmap");
    exit(1);
}

失败并显示

mmap: Bad file descriptor

我对

mmap()
没有太多经验,但我们的应用程序确实使用它来创建从 PL 中的内存空间到应用程序内存空间的映射,这与我现在需要的相反。另外,我想知道是否存在任何与缓存相关的问题,例如一旦 PL 写入缓冲区,从 PS 读取是否会立即看到数据?

还有一件事 - 我在我的 Ubuntu PC 工作站上运行上面的代码,而不是 PetaLinux。还没有准备好。我不知道我是否收到此错误,因为它不在实际平台上。

mmap memory-mapping zynq-ultrascale+
1个回答
0
投票

我确实解决了这个问题,但直到我意识到我的想法完全错误。 首先,上面提议的代码是由其中一个 LLM AI 开发的,这显然是幻觉。正确的做法可以概括为:

  1. 在您的Petalinux 设备树文件中定义一些保留内存。这将允许您指定内存块基址的物理或“总线地址”及其长度。就我而言,当 PL 写入 PS RAM 时,这是 PL 的 DMA 内存控制器(使用 Vivado)中指定的地址,并成为比特流的一部分。 使用更新的设备树重建 Petalinux
  2. 如果您想访问 PL 中存在的某个内存地址,请使用 mmap() 执行“完全相同的操作”。有多个链接讨论如何执行此操作。这将为您提供一种通过物理地址读取或写入的方法。
  3. 这是短篇小说。虽然省略了很多步骤,但大致思路是这样的。

我一路上发现了一些很好的资源:

设备树:为大家介绍硬件!

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842482/Device+Tree+Tips

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.