0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于DWC_ether_qos的以太网驱动开发-描述符链表介绍

嵌入式USB开发 来源:嵌入式USB开发 作者:嵌入式USB开发 2023-08-30 09:39 次阅读

本文转自公众号欢迎关注

一.描述符概述

1.0 前言

对于DWC Ethernet QoS驱动的编写来说,初始化完成之后,核心操作就是DMA的描述符链表配置(linked list of descriptors)。DMA根据描述符链表自动在FIFO和用户指定的缓存之间搬运数据。对于熟悉新思的IP的用户来说,这种套路会有似曾相识的感觉,没错新思的大部分高速IP的数据流都是这么处理的,比如在DWC2 USB的IP中就是Scatter/Gather DMA,叫法不一样,实现和思想基本是一样的。这种方式可以解放CPU,使用DMA根据描述符链表搬运数据,对于高速数据流的流式处理有利,相对单个描述符的DMA,链表式描述符一次可以处理更多数据更高效,且能够实现环形不间断流式处理。

参考手册《21 Descriptors》

1.1描述符类型

Normal Descriptor: 描述要传输的数据包和其控制信息。包含两个缓冲区和两个地址指针,这种设计以实现较大的灵活性,支持不同的内存管理方案。

Context Descriptor: 描述要传输的数据包的控制信息。

注意:单个数据包可以使用的描述符数量没有限制,虽然这里没有限制,但是受限于Ring_Length寄存器,描述符链表实际最多只能配置为0x3FF即1024个描述符。

1.2描述符结构

描述链表整体看是一个环形结构即到了描述符的末尾可以绕回.

图片

有一些寄存器对该环形描述符进行定义

1.2.1描述符的颗粒(间隙)

收发都是一样的

图片

上述描述Descriptor n本身的大小是固定的即RDES0~RDES3,4个WORD(根据不同的总线宽度和大小端,有不同的layout,但是其大小总是4个WORD大小,见后面说明).

还支持描述符之间有间隙,间隙的单位根据总线宽度而定,即32,64,128位总线宽度分别对应 Word, Dword, Lword为单位,寄存器DMA_CH(#i)_Control的DSL位域即用于描述该间隙。

再次提醒注意,这里的单位是根据总线宽度而定,不是固定为WORD。

图片

图片

比如这里DSL=0,则表示描述符之间没有间隙,

设置为1,如果是32位总线则间隙为1 WORD。

图片

1.2.2描述符的个数

收发分别由如下寄存器指定

DMA_CH(#i)_TxDesc_Ring_Length

DMA_CH(#i)_RxDesc_Ring_Length

图片

图片

1.2.3描述符的首末地址

1)发由以下寄存器决定:

基地址

DMA_CHi_Tx_Control的ST=0,即TX停止时才能修改以下寄存器。

DMA_CH(#i)_TxDesc_List_HAddress 发送描述符链表基地址的高位,只有40,48位地址模式才使用。

DMA_CH(#i)_TxDesc_List_Address 发送描述符链表基地址的低位,必须根据总线宽度按照Word, Dword,Lword对齐,DMA会自动根据总线宽度忽略低位。

尾地址

DMA_CH(#i)_TxDesc_Tail_Pointer 发送描述符链表尾地址,必须根据总线宽度按照Word, Dword,Lword对齐。

这里为什么没有高位寄存器了呢,因为不需要了,高位和DMA_CH(#i)_TxDesc_List_HAddress一样。

2)收由以下寄存器决定 :

基地址

DMA_CH(#i)_RX_Control 的SR=0,即RX停止时才能修改以下寄存器。

DMA_CH(#i)_RxDesc_List_HAddress 接收描述符链表基地址的高位,只有40,48位地址模式才使用。

DMA_CH(#i)_RxDesc_List_Address

接收描述符链表基地址的低位,必须根据总线宽度按照Word, Dword,Lword对齐,DMA会自动根据总线宽度忽略低位。

尾地址

DMA_CH(#i)_RxDesc_Tail_Pointer接收描述符链表尾地址,必须根据总线宽度按照Word, Dword,Lword对齐。

这里为什么没有高位寄存器了呢,因为不需要了,高位和DMA_CH(#i)_RxDesc_List_HAddress一样。

1.2.4当前处理的Buffer地址

以下只读寄存器可以调试使用,确认当前处理的描述符对应的Buffer地址,reset时这些寄存器会清零。

发送Buffer

DMA_CH(#i)_Current_App_TxBuffer_H 地址高位

DMA_CH(#i)_Current_App_TxBuffer 地址低位

接收Buffer

DMA_CH(#i)_Current_App_RxBuffer_H

DMA_CH(#i)_Current_App_RxBuffer

需要有收发数据才会更新当前处理的Buffer地址。

1.2.5当前描述符指针

以下只读寄存器可以调试使用,确认当前处理的描述符,reset时这些寄存器会清零。

发送

DMA_CH(#i)_Current_App_TxDesc

接收

DMA_CH(#i)_Current_App_RxDesc

Current寄存器是什么时候更新的呢,测试可以知道是写Base寄存器时更新

图片

进一步测试可知是在DMA停止,即DMA_CH(#i)_RX_Control的SR为0时写DMA_CH(#i)_RxDesc_List_Address 时Current寄存器会自动设置为DMA_CH(#i)_RxDesc_List_Address的值。如果SR=1则不会。

TX也类似。在DMA工作之后,该寄存器更新为当前正在处理的描述符。

1.3描述符的内存布局

描述符的大小总是4x4字节的,但是其布局和总线宽度和大小端有关。

且必须根据总线宽度Word, DWord,或 LWord 对齐。

三种总线宽度,2种大小端模式一共有6种组合

32位的大端和小端

图片

64位小端

图片

64位大端

图片

128位小端

图片

128位大端

图片

1.4描述链表的工作过程

1.4.1环形结构

图片

前面介绍的描述符首末地址,当前描述符指针和描述符个数这几个寄存器决定了链表的行为。

DMA可以处理的描述符范围是:[Base,Tail)

注意[]表示包括本身,()表示不包括本身,即包括Base寄存器对应的描述符,不包括Tail寄存器对应的描述符。

当前描述符指针则从Base到Tail-1的位置遍历,当Current=Tai时DMA停止工作。

同时还受描述符个数寄存器限制,

如果描述个数设置为N,则Current到Base~N-1的位置之后会绕回到Base,即以N个为单位回环,这里假设Tail是在N个描述符之后的,如果在之前则回环之前就Current=Tail停止了。

1.4.2停止条件:

Current=Tail

或者Current的位置没有就绪的描述符,即不是Owned by DMA的描述符。

所以Tail至少要大于base才能传输。

1.4.3重启条件

重启条件即保证current处的描述符就绪,且current%N

写Tail寄存器时会触发一次硬件的重启条件检测,来检测上述条件。

所以停止了之后读写 都需要写Tail寄存器才能重启

1.4.4几种情况分析

Tail 指向 N-1位置之后,此时current不可能达到tail,因为到N-1时就绕回了,

所以停止条件只能是current处的描述符未就绪,即不是Owned by DMA。

此时current不断回环遍历,只要软件能保证current处的描述符一直就绪,DMA就一直传输处理,形成了不间断的持续流处理。

图片

Tail刚好指向N-1位置或者更向前

则当current=current后停止。

或者current处的描述符未就绪即停止。

此时没法形成持续的流,因为current到了tail之后就会停止。

图片

1.4.5驱动的设计

为了充分利用上述描述符的回环模式,能够连续不断的收发,需要保证DMA处理完之前就更新好后续描述符。使得DMA一直有描述符能处理,不至于current处描述符未就绪而导致停止,且tail设置为在N个描述符之后,这样current始终不会因为=tail而停止。

要保证连续不断的流,需要软件准备描述符的速度大于等于DMA处理描述符的速度。

即current处始终有描述符可以处理,所以软件准备好的描述符在current及其之后,需要软件维护一个变量index记录当前软件准备好的描述到了哪。

即current追赶index。

当index>current时,[current,index)之间是已经准备好的描述符待DMA处理的,[index,Tail)

[base,current)这两部分是DMA已经处理完,软件需要更新的描述符。

图片

当index<=current时,[index,current)是DMA已经处理完,软件需要更新的描述符。

[current,Tail),[Base,index)这两部分是DMA未处理的部分。

图片

所以驱动处理流程如下

初始化时先尽可能多的填充好描述符,对于接收可以初始化所有描述符为接收状态,对于发送当然刚开始可能并不需要发送很多数据,那么就需要发送多少就准备多少描述符。

然后接收中断中处理DMA已经接收完的描述符,应用处理完对应的数据后再将这些描述符设置为接收状态。

对于发送则查询哪些描述符DMA已经发送完就可将其更新为发送状态进行发送。

比如如下开始准备了n个描述符

图片

然后启动DMA传输,

此时有两种情况,一种是硬件处理DMA比如软件更新描述符块,还有一种是相反。

后者软件总是在current追不上index,即软件更新描述符速度大于硬件处理描述符速度

一段时间后可能就是如下所示

图片

而前者软件准备的慢则current会追上index此时DMA会停止,软件需要重新准备描述符并重新配置Tail来重启DMA。

具体的驱动代码后面再详讲。

1.5总结

以上介绍了描述符链表,尤其需要了解环形链表的工作模式何时启动,何时停止,软件和硬件如何配合使用环形链表。以及相关寄存器的值的含义和何时更新。了解以上机制后后面就可以开始编写驱动代码进行收发。下回再详讲。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5068

    文章

    19008

    浏览量

    302902
  • 以太网
    +关注

    关注

    40

    文章

    5371

    浏览量

    171025
  • 寄存器
    +关注

    关注

    31

    文章

    5308

    浏览量

    119975
  • 驱动
    +关注

    关注

    12

    文章

    1824

    浏览量

    85167
  • dma
    dma
    +关注

    关注

    3

    文章

    559

    浏览量

    100411
收藏 人收藏

    评论

    相关推荐

    基于DWC2的USB驱动开发-IAD描述符详解

    本文转自公众号,欢迎关注 基于DWC2的USB驱动开发-IAD描述符详解 (qq.com) 一.  前言 IAD描述符用于一个设备功能关联多
    的头像 发表于 06-27 08:45 5.2w次阅读
    基于<b class='flag-5'>DWC</b>2的USB<b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-IAD<b class='flag-5'>描述符</b>详解

    基于DWC_ether_qos以太网驱动开发-MAC帧格式介绍

    本文转自公众号,欢迎关注 基于DWC_ether_qos以太网驱动开发-MAC帧格式介绍 (qq.com) 一.前言   在
    的头像 发表于 08-30 09:23 2213次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-MAC帧格式<b class='flag-5'>介绍</b>

    基于DWC_ether_qos以太网驱动开发-MDIO驱动编写与测试

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-MDIO驱动编写与测试 一.前言
    的头像 发表于 08-30 09:37 3604次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-MDIO<b class='flag-5'>驱动</b>编写与测试

    基于DWC_ether_qos以太网驱动开发-数据流验证过程

    转自公众号欢迎关注 https://mp.weixin.qq.com/s/klrHhaLMM_0W3FGVwHXFkA 基于DWC_ether_qos以太网驱动开发-数据流验证过程
    的头像 发表于 08-31 08:41 1886次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-数据流验证过程

    基于DWC_ether_qos以太网驱动开发-收发驱动编写与调试

    本文转自公众号,欢迎关注 基于DWC_ether_qos以太网驱动开发-收发驱动编写与调试 (qq.com) https://mp.wei
    的头像 发表于 09-05 08:47 2208次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-收发<b class='flag-5'>驱动</b>编写与调试

    基于DWC_ether_qos以太网驱动开发-无OS环境移植LWIP

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-无OS环境移植LWIP (qq.com) https://mp.weixin.qq.com/s
    的头像 发表于 09-06 08:40 1491次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-无OS环境移植LWIP

    基于DWC_ether_qos以太网驱动开发-LWIP的堆管理介绍

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-LWIP的堆管理介绍 (qq.com) https://mp.wei
    的头像 发表于 09-08 08:40 1199次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-LWIP的堆管理<b class='flag-5'>介绍</b>

    基于DWC_ether_qos以太网驱动开发-RTOS环境移植LWIP与性能测试

    本文转自公众号,欢迎关注 基于DWC_ether_qos以太网驱动开发-RTOS环境移植LWIP与性能测试 (qq.com) https://mp.weixin.qq.com/s
    的头像 发表于 09-11 11:20 1910次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-RTOS环境移植LWIP与性能测试

    基于DWC_ether_qos以太网驱动开发-LWIP在PC上进行开发调试

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-LWIP在PC上进行开发调试 (qq.com) https://mp
    的头像 发表于 09-11 08:40 1893次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-LWIP在PC上进行<b class='flag-5'>开发</b>调试

    以太网描述符ETH_DMATxDesc_OWN异常

    stm32 以太网发送一段时间后发送描述符状态一直为DMA拥有,造成以太网发送停止,发送过程中什么原因会造成描述符一直为DMA拥有;(发送接收同时进行,接收为中断接收)`&a
    发表于 07-07 14:08

    设计软件核心以太网服务质量数据手册免费下载

    本文描述Synopsys设计软件核心以太网服务质量DWC以太网QoS核心5.10A。DWC
    发表于 10-23 08:00 16次下载
    设计软件核心<b class='flag-5'>以太网</b>服务质量数据手册免费下载

    DesignWare核心以太网服务质量数据本

      本文档介绍Synopsys DesignWare核心以太网服务质量(DWC_Ethernet_qos)核心,5.10a。DWC_Ethernet_qos实现了与MAC层相关的
    发表于 03-31 15:11 3次下载

    基于DWC_ether_qos以太网驱动开发-包过滤

    以太网上数据非常多,如果所有数据都接收交给软件去处理软件负载会非常重,所以一般只需要接收发给自己的数据即可
    的头像 发表于 09-02 09:19 1616次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-包过滤

    基于DWC_ether_qos以太网驱动开发-描述符格式介绍

    前面我们介绍描述符链表的工作模式,重点是了解环形链表是如何环形的,以及相关的寄存器。驱动编写就需要更进一步,了解
    的头像 发表于 09-04 14:14 2379次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>描述符</b>格式<b class='flag-5'>介绍</b>

    聊一聊以太网发送描述符

    相对于其他总线,以太网的知识庞杂,当然,可获取的资料也丰富。以太网的知识从驱动层到上层协议栈,很难一下消化,所以,不妨从点开始,不断地拓展和链接,从而形成完整地以太网知识框架,进而更好
    的头像 发表于 10-22 15:09 194次阅读
    聊一聊<b class='flag-5'>以太网</b>发送<b class='flag-5'>描述符</b>