继续梳理以太网的DMA描述符。
以太网DAM描述符的结构
有两种结构,链式结构和环形结构。
常用的是链式结构。
标准库中,关于DMA描述符的数据结构
以gd32f4xx_enet.c为例。
先说发送描述符。
系统分配了5个发送描述符。每个描述符对应的缓冲区大小为1524字节。
#define ENET_TXBUF_NUM 5U /*!< ethernet Tx DMA descriptor number */#define ENET_MAX_FRAME_SIZE 1524U /*!< header + frame_extra + payload + CRC */ #define ENET_TXBUF_SIZE ENET_MAX_FRAME_SIZE /*!< ethernet transmit buffer size */enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */
注意,这里有一个5个元素的结构体数组:txdesc_tab,这就是发送描述符表;还有一个2维数组tx_buff,是5*1524个字节,这就是发送缓冲区;后面要说怎么用。
描述符初始化
调用以下函数初始化发送DMA描述符为链式结构:
enet_descriptors_chain_init(ENET_DMA_TX);
初始化完成之后的效果:(借用网上的图)
这张图也挺好:
初始化后内存中的数据和DMA寄存器
5个描述符的地址分别为0x20000134、0x20000144...0x20000174。
并且,第一个描述符的next_desc_addr指向第二个描述符。
同样的,第二个的next指向第三个。。。最后一个的next指向第一个:
再看缓冲区的地址:
分别为0x20001F48、0x2000253C、0x20002B30、0x20003124、0x20003718。
描述符中的buffer1_addr分别指向各自的缓冲区:
DMA组的发送描述符表寄存器DMA_TDTADDR中保存的是第1个描述符的地址0x20000134
使能ENET后,当前的发送和接收描述符级缓冲区地址也已更新(只读寄存器):
验证运行过程中的状态
测试条件及方法:
查看当前的寄存器。
当前接收描述符地址:0x200000F4(描述符1);
当前接收缓冲区地址:0x20000778(缓冲区1);
看看缓冲区里面的数据: