This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] PROCESSOR-SDK-AM57X:从使用 CMEM 转换到 dma-heap/dma-buf

Guru**** 2540720 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1557322/processor-sdk-am57x-transitioning-from-using-cmem-to-dma-heap-dma-buf

器件型号:PROCESSOR-SDK-AM57X


工具/软件:

我正在尝试使用 SDK9.03、在 AM57x 上从使用 CMEM 过渡到使用 DMA-heap/dma-bufs。

现有应用程序在用于 DSP1 的 OCMC 中有一个内存 CMEM 区域、此内存在 DSP 和 ARM 之间共享。 存储器分为不同的区域、并且当特定区域的控制从一个处理器转移到另一个处理器时、DSP 和 ARM 会使缓存无效。 就 CMEM 而言、有一个存储器区域、但 DSP 和 ARM 使用的大约 40 多个不同的较小区域。

我已经尝试使用 dma-heap、添加了一个保留的内存区域、并看到了相应的/dev/dma_heap/my_reserved_memory 器件文件。 alloc ioctl 可用于获取 dma-buf、同步 ioctls 可用于控制整个保留存储器区域的高速缓存。 这对于简单的演示来说是可以的、但对于现有应用来说是不够的。

我希望 alloc ioctl 实际上可以分配一部分保留的内存,但这似乎不是这样的情况。 只有一个存储器块、不清楚如何将其分成几个部分。 同步 ioctls 似乎仅在 dma-buf 的整个存储器块上运行。

可以指定多个保留的存储器区域(最多 7 个具有默认内核代码、或者更改为#define 和重建内核的存储器)、但似乎必须在设备树中放入比预期更多的信息。

是否可以指定池详细信息以便 dma-heap 池是多个块而不是一个块? 似乎 genalloc 系统有一定的能力支持这种设备,但 carveout-dma-heap 代码似乎没有利用这一点。

Linux 用户程序如何无需在器件树中指定低级详细信息即可获得对存储器特定区域的缓存控制?  这是 cmem 实现的。 如何使用 dma-heap 和 dma-bufs 来实现这一点? 我是否误解了 dma-heap/dma-buf 的功能?  是否 唯一可用的 替代方案是保留 40 多个 DMA 堆内存区域?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、John:

    我将在内部进行商谈、并在本周就这件事回复您。

    -Josue

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、John:

    首先、我想重申一下、SDK 8.2 中删除了大数据 IPC 示例。

    其次、内存池不应在 OCMC ram 中使用、而应仅在 DDR 中使用。

    您能帮助我了解您如何得出以下结论吗?

    希望 alloc ioctl 实际上可以分配一段保留内存、但事实似乎并非如此。 只有一个存储器块、不清楚如何将其分成几个部分。 同步 ioctls 似乎仅在 dma-buf 的整个内存块上运行。

    -Josue

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不是从大数据示例开始。 它实际上是一个使用 CMEM 的客户提供的简化的实际应用示例。

    很遗憾听到它仅适用于 DDR。 CMEM 似乎与 OCMC 工作正常。

    我认为可以从单个 DMA 堆中进行多个分配是一个错误的假设。 我可能应该意识到,“ alloc“ ioctl 根本不像 malloc ,因为没有任何方法来回馈分配的东西。

    我切换到尝试使用只有 3 个不同堆的 DDR 来实现循环队列。 读取索引是一个在 ARM 上具有读取/写入访问权限的堆。 写入索引是在 ARM 上具有只读访问权限的第二个堆。 缓冲区是 ARM 上具有只读访问权限的第三个堆。  在使用 CMEM 的旧 SDK 6 上也使用了类似的内存用法。

    使用新的 SDK9 并尝试使用 dma-heap 而不是 CMEM、我得到的结果非常不一致。 初始化让 ARM 打开堆、分配缓冲区以获取 dma-buf 文件描述符、并获取通过 RpMSG 发送到 DSP 的物理地址。

    具有读取/写入访问的读取索引会获得 DMA_BUF_SYNC_START、该值被设置为初始值、然后执行 DMA_BUF_SYNC_END 以希望进行缓存回写 (Cache_WB) 以将值获取到 DDR。 然后、完成另一个 DMA_BUF_SYNC_START、以便读取索引的正常状态在 SYNC_START 中由 ARM 控制。 当读取索引递增时、写入该值、然后执行 SYNC_END 和 SYNC_START 序列以将新值写入存储器、并以开放的 SYNC_START 状态结束。

    当 DSP 获得 RpMSG 时、它会将物理地址转换为虚拟地址。 然后、读取初始读取索引值(在 Cache_inv 之后)、并将其写入写入索引、使循环缓冲区看起来为空。 在写索引上完成 Cache_Wb()、以将值推入内存。 然后、向 ARM 发送回复消息。

    当 ARM 收到回复消息时、它会对写索引执行 SYNC_START、希望执行 Cache_inv、然后读取写索引值。 它期望此值是初始读取索引值、但情况并非总是如此。

    这个初始序列看起来非常简单、但结果并不一致。

    DSP 似乎经常无法获得正确的初始读取索引值。 ARM 并不总是从 DSP 获取写入索引值。 我已经尝试在 ARM 上使用 devmem2 来验证这些值、有时似乎 DSP 中的值未写入 DDR、有时似乎 devmem2 显示了正确的写入索引值、但测试程序在读取写入索引时未看到正确的值。

    在 ARM 或 DSP 上、缓存例程似乎都没有按预期工作。 我不确定如何处理或核实这一点。  

    当我的沮丧程度下降时、我可能会整理一个可以发布的更简单的程序。  现在、如果上述任何一项提示您提出任何建议、我们将非常感谢您提供这些建议。

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    John、

    由于 BW、我将在下周回顾一下。

    -Josue

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    John、

    本周我没有时间。  

    感谢您的耐心。

    -Josue