你好
我只是想了解 ENET_QOS 的 DMA 功能。我现在的 DMA_CHx_RXDESC_TAIL_POINTER 寄存器有问题。在登记册的描述中,我在参考手册中找到了以下内容:
61.7.1.479.2功能
通道 0 Rx 描述符尾部指针指向基站的偏移量,表示最后一个有效描述符的位置。
因此,应在此处输入最后一个有效描述符的地址。如果环中有 8 个条目,则最后一个条目为 7。从 0 数到 7。
但是,如果我看看 ENET_QOS_ReadFrame 的结尾,这里使用了下面一行代码:
/* Always try to start receive, in case it had stopped */
rxDescTail = (uint32_t)(uintptr_t)&rxBdRing->rxBdBase[rxBdRing->rxRingLen];
#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
rxDescTail = MEMORY_ConvertMemoryMapAddress(rxDescTail, kMEMORY_Local2DMA);
#endif
base->DMA_CH[channel].DMA_CHX_RXDESC_TAIL_PTR = rxDescTail;
base->DMA_CH[channel].DMA_CHX_RX_CTRL |= ENET_QOS_DMA_CHX_RX_CTRL_SR_MASK;但此处 rxDescTail 并未设置为有效描述符,而是使用了"境外" 访问。rxBdRing->rxRingLen 是环的大小。
这种情况也发生在其他地方。是这里出错了,还是 DMA_CHx_RXDESC_TAIL_POINTER 究竟应该如何使用?
致以最诚挚的问候,
Michael
你好@Gavin_Jia、
"MCUXpresso SDK 将其设置为单快结束,以防止 Rx DMA 因电流 == 尾端而停止;"
因此,尾部指针被设置在环外,这样,如果电流 == 尾部,DMA 就不会停止。
然而,ENET_QOS_SendFrame 的情况却令人困惑。在这里,尾部指针比当前指针前移一个条目。这样做是为了在发送完当前帧后停止 DMA 吗?这意味着,如果发送环的大小也是 8,而要发送的新帧位于索引 5 中,则尾指针将被设置为 6。
但如果要发送的新帧在索引 7 中,尾指针将不会设置为索引 0,而是设置为索引 8。 之后,如果在 7 之后使用索引 0,尾部指针将设回 x+1,即 0+1。
我完全不明白为什么要在这里设置尾指针。在这种情况下,将其设置为索引 8 不就可以了吗?因为如果没有为下一个索引设置 OWN 位,DMA 就不会在发送后继续运行。
致以最诚挚的问候,
Michael
感谢您对 NXP MIMXRT 系列的关注!
SDK 代码是有意为之。&rxBdBase[rxRingLen]用作单次快结束尾边界/门铃值,而不是用作软件或 DMA 访问的描述符。在 ENET_QOS DMA 环模式下,描述符环长度寄存器定义实际有效的描述符范围,而尾部指针用于指示边界,并在 DMA 停止时重新启动。
因此,对于 8 个描述符的环,有效描述符仍然是索引 0~7,而&rxBdBase[8] 的值仅用作尾部边界。
《参考手册》中的 “最后一个有效描述符” 的措辞很容易被误解。更精确的描述是,尾指针标记描述符边界/DMA 恢复点。MCUXpresso SDK 将其设置为单次快结束,以防止 Rx DMA 因当前 == 尾端而停止;DMA 仍根据编程的环长度缠绕,并且不会获取超出绑定的描述符。
致以最诚挚的问候,
Gavin
你好@Gavin_Jia、
是否有关于 ENET_QOS_SendFrameFunktion 的新信息?
致以最诚挚的问候,
Michael
很抱歉这么晚才回复,几天前我休假不在办公室。请接受我诚挚的歉意。
您对 Rx 端的理解是正确的:SDK 使用 Rx 环的单次传送结束地址作为尾部边界。这并不意味着 DMA 访问了一个越界描述符。
对于 Tx 路径,在ENET_QOS_SendFrame() 中动态更新尾指针也是有意为之。在 ENET_QOS 环模式下,描述符尾指针应理解为 DMA 可用描述符窗口的结束边界,而不是 DMA 必须获取的描述符。DMA 处理的描述符最多但不包括尾指针。当当前描述符指针到达尾部指针时,DMA 会暂停或等待软件发布更多描述符。
例如,Tx 环有 8 个描述符:
- 有效描述符:索引 0 至索引 7
- 单快端边界:&ring[8]
如果软件只准备传输描述符索引 5,尾部指针将设置为&ring[6] 。这意味着允许 DMA 处理[5, 6) 的范围,因此它只处理描述符 5。之后,当前指针到达尾部边界,DMA 等待下一次尾部更新。
如果软件准备了描述符索引 7,尾部指针将设置为&ring[8] 。&ring[8] 的值只是一个单播端边界地址。它不是 DMA 抓取的有效描述符。实际的环绕由已编程的描述符环长度控制,因此有效的描述符仍然是索引 0 至索引 7。
环包络后,软件随后准备描述符索引 0,新提交的范围变为[0, 1) ,因此尾指针更新为&ring[1] 。
关于 OWN 位:OWN 位和尾部指针的作用不同。OWN 位表示单个描述符是属于 DMA 还是属于应用程序。尾指针定义软件向 DMA 发布描述符的距离,在响铃模式下,写入尾指针还可用作门铃/恢复指示。
因此,将 Tx 尾指针永久保留在&ring[8] 与 SDK 的实现方式不同,也不是推荐的解释。尽管 DMA 在到达 OWN 位未设置的描述符时可能会停止,但仍需要更新尾指针以发布新准备的 Tx 描述符,并通知/恢复 DMA。
总结:
&ring[ringLen] 。致以最诚挚的问候,
Gavin
你好@Gavin_Jia、
非常感谢你的详细解释。
致以最诚挚的问候,
Michael