大家好、
我正在尝试实施 EVE 应用程序、将两个16位值合并为一个32位值。 目标是使用新计算出的值覆盖输入缓冲器中的值、以便我只处理一个组合输入/输出缓冲器、而不是两个单独的缓冲器。 这在 VCOP 上是可行的、还是 VCOP 内核始终包含一个指定的输入和输出缓冲器(IbufL 和 IbufH)?
如果可能、我可以将 IbufL 和 IbufH "合并"到一个缓冲区、以便我处理32kB 而不是16kB 的数据、而不重新布局缓冲区(通过 EDMA)吗?
此致、
托比亚斯
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.
大家好、
我正在尝试实施 EVE 应用程序、将两个16位值合并为一个32位值。 目标是使用新计算出的值覆盖输入缓冲器中的值、以便我只处理一个组合输入/输出缓冲器、而不是两个单独的缓冲器。 这在 VCOP 上是可行的、还是 VCOP 内核始终包含一个指定的输入和输出缓冲器(IbufL 和 IbufH)?
如果可能、我可以将 IbufL 和 IbufH "合并"到一个缓冲区、以便我处理32kB 而不是16kB 的数据、而不重新布局缓冲区(通过 EDMA)吗?
此致、
托比亚斯
您好 Tobias、
您的问题有两个部分。 一种是重复使用 EVE 的内部存储器、另一种是与外部存储器之间的内部缓冲器 DMA。 我正在为这两个问题写我的答复:
第1部分:重复使用 EVE 的内部存储器
VCOP 对内部缓冲器没有限制、您可以对同一缓冲器进行读写。 但是、您应该确保您不会从您所写的同一位置读回内容、因为这可能会导致比赛条件、因为商店和货物是独立发生的。 另一个需要考虑的因素是对性能的影响、因为您将读取和写入同一个缓冲区、如果您对不同缓冲区进行读取和写入、则需要2个周期、而不是1个周期。 关于使用32KB 全部存储器的问题、同样、VCOP 对存储器没有限制、但问题将出现在 DMA 中、我 将在本视频的第二部分对此进行解释
第2部分:内部缓冲器到外部存储器的 DMA。
如果您将32KB 的全部内容用于输入、并将其重新用于输出、则 DMA 会出现问题、因为您必须将32KB 的数据从外部存储器 DMA 传输到内部存储器、同时必须将已计算的32KB DMA 处理完 从内部存储器到外部存储器的数据。 如果您在写入新数据之前先将所有计算的数据从 DMA 中取出、则可以执行此操作。 因此、在对 DMA 进行编程时应小心谨慎。
此致、
安州
您好、Anshu、
是的、我正在使用别名存储器视图。 内核用于处理两个10位输入值(存储在16位缓冲区中) 并将其合并为一个20位值(存储在32位缓冲区中)。 这意味着我们的输入是输出的两倍。 这是等效的 C 代码:
uint16 *pFrameAdd16 =(uint16*) ipcMsg->frameAddr; uint32 *pFrameAdd32 =(uint32*) ipcMsg->frameAddr; uint32 numPixel = ipcMsg->vPixel * ipcMsg->hamePixel; for (uint32*) ipcAdd16+<uint32 *(uint32) i)<uint1 +[frameixel <uint32](uint32)<uint1 +[framex 32)<uint32 +[framex <uint32
我生成的内核代码如下所示:
#define ELEMSZ sizeof (* in1_ptr) #define VECTORSZ (VCOP_SIMD _width*ELEMSZ) #define shift (10) void buffer_merge ( __vptr_uint16 in1_ptr、 __vptr_UINT32 optr、 unsigned short width、 unsigned short height ) { __vector Vin1; __vector Vin2; __vector Vout; __Vector Vinshift; __vector Vin1s vector v1s;__vector vector v1 vector v1 vector v1 vector v Vshift = shift; 对于(int I1 = 0;I1 <高度;I1++) { 对于(int I2 = 0;I2 <宽度/VCOP_SIMD 宽度;I2++) { _agen Addr_out; ADDR_OUT = I1*width*ELEMSZ*2 +I2*VECTORSZ*2; (Vin1、Vin2)= in1_ptr[Addr_out].deinterleave (); Vin1s=(Vin1 << Vshift); 输出电压 = Vin1s | Vin2; OPTR[Addr_OUT]=输出电压; } }
Hi Pramod,
__vptr_uint16 in1_ptr:指向 VCOP buf 的指针,在本例中(uint16_t*) 0x40050000
__vptr_uint32 optr:指向同一 VCOP 缓冲器的指针,因为我想将整个 VCOP 存储器用作一个输入/输出缓冲器,所以这里是(uint32_t*) 0x40050000
无符号短宽度:连续的输入像素数、此处为16384
无符号短高度:在本例中为1、因为我要以2D 方式处理后续数据、而不是数据
此致、
托比亚斯
您好、Anshu、
非常感谢您在我的内核上提供提示。 我在初始内核代码中使用的宽度是正确的。 它太大、因此在最后一个 VCOP 周期中超出了存储器边界。 我修复了这一问题、现在我的应用程序不会陷入循环中、也不会再抛出错误。
我还尝试了您对内核的改进、并进行了一些更改(例如将 VCOP_SIMD 宽度更改为16)、效果很好。
如前所述、我的应用程序现在始终在完成时不会出现与代码相关的错误、但我遇到了另一个问题:每当我选择大于或等于16kB 的 VCOP 缓冲器大小时、我的输出缓冲器包含错误的值。 每次我重新启动应用程序时、这些值始终从不断变化的位置显示、甚至不接近于预期值。
奇怪的是、这些错误/错误值仅在我启动我的应用时出现、而没有任何断点(直接在 EVE/TDA3x 上)。 如果我使用断点运行它并通过它进行调试、则所有值都是可以的。 在 EVE 仿真器中、输出看起来也很好(代码中有和没有断点)。 我是否 需要注意运行时问题? 或者这可能是 EDMA 错误吗?
附加的图像显示错误的值。 预期值应始终比上一个值高一、直到[2098039]。
再次感谢大家的问候!
托比亚斯