本文转自公众号,欢迎关注
基于DWC_ether_qos的以太网驱动开发-收发驱动编写与调试 (qq.com)
https://mp.weixin.qq.com/s/NXKiBsNvhMG_bCruEeqmtg
一.前言
前面已经介绍了环形描述符的工作方式和描述符的具体格式。收发的驱动实际就是围绕着准备描述符来进行的,这种机制使得驱动代码的编写比较简单了,软件通过描述符高速硬件DMA怎么做即可,剩下的就交给硬件DMA了,这样效率非常高。
二.收发驱动
2.1发送
Current是硬件维护的指针,Current表示硬件当前操作的描述符,如果该描述符不是OWN BY DMA则停止。
Inx是软件维护的指针,软件写完一个描述符Inx递增,如果Inx追赶上了Current,即遇到了OWN BY DMA的描述符也停止。
开始时指针如下,Current,Inx都从Base开始,注意current需要启动后才能读到值,初始化后是0,所以这里编程需要注意
软件准备n个描述待发送,黄色部分,并设置这些描述符OWN BY DMA,启动DMA,硬件开始处理这些描述符
比如硬件处理完一个描述符后,继续处理后面的
硬件处理完,Current追上了Inx,停止DMA
当然Current在发送的时候,软件又可以从Inx往后面准备描述符,相当于Inx是生产者,生产描述符,Current是消费者,消费描述符,这样就可以不间断的进行发送。
/**
2.2接收
接收和发送类似
初始化时先将所有描述符设置为接收状态,且设置产生IOC中断,并启动DMA。
如下所示黄色描述符都是表示准备接收数据。
在收到一包数据后,产生中断,如下描述符0即接收到数据的描述符,变为非OWN BY DMA,软件查询该描述符可以获取到接收数据长度等信息,进行处理。
软件处理完描述符0之后,又可以将其设置为接收状态OWN BY DMA以便接收继续接收。
以上是接收比软件处理的慢,所以Current一直追不上Inx,如果接收比软件处理的快,
则Current会追上Inx而停止。
比如如下
int iot_eth_receive_handle(eth_ctrl_t *p_ctrl,eth_rcv_data_pf cb)
接收由于要处理包数据所以花费时间比较大,一般不在中断中处理数据,也就是不在中断中调用iot_eth_receive_handle,而是查询方式调用iot_eth_receive_handle,或者接收IOC中断时中断中发送信号量或者设置标志,主线程主循环中接收信号量或标志才调用该函数进行接收处理。
三.接收调试
收发数据流参考https://mp.weixin.qq.com/s/klrHhaLMM_0W3FGVwHXFkA
的验证过程吗,按照MAC回环,PHY回环,和PC通讯的过程测试。
3.1检查描述符相关
接收调试主要关注以下描述符相关寄存器
检查RxDesc_List,RxDesc_Tail 是否设置正确,检查RxDesc_Ring_Length描述符个数是否设置正确。检查RxDesc和RxBuffer是否递增变化。
(gdb) x /28xw 0x01161100
0x1161100: 0x00000000 0x00100001 0x00100be1 0x00000000
0x1161110: 0x00000000 0x0200c120 0x00000000 0x0200bd00
RxDesc_List
0x1161120: 0x0200c510 0x00000000 0x0200bd00 0x0000003f
RxDesc_Tail
0x1161130: 0x00000001 0x0000c8c3 0x00000000 0x00000000
RxDesc_Ring_Length
0x1161140: 0x00000000 0x0200c510 0x00000000 0x0200bd10
RxDesc
0x1161150: 0x00000000 0x0200bd20 0x00000000 0x0200b710
RxBuffer
0x1161160: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
0x111C RxDesc_List
0x1128 RxDesc_Tail
0x1130 RxDesc_Ring_Length
0x114C RxDesc
0x115C RxBuffer
3.2 确认回写状态和缓存数据是否有
(gdb) p rx_desc
$5 = {{
des0 = 0x200b120,
des1 = 0x0,
des2 = 0x0,
des3 = 0xc1000000
}, {
des0 = 0x200b710,
des1 = 0x0,
des2 = 0x0,
des3 = 0xc1000000
}}
(gdb) p /x rx_buffer
$6 = {0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0x0, 0x42, 0xaa, 0x55 , 0x15, 0x13, 0x86, 0x4a, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x0 , 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0x0, 0x42, 0xaa, 0x55, 0x15, 0x13, 0x86, 0x4a, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x50, 0x0, 0x0, 0x30, 0x0 }
(gdb)
3.3 确认接收状态
如果以上描述符都正确但是还是没有数据,确认接收是否正在工作
查看DMA_Debug_Status0寄存器
RPS0是3表示Running
(gdb) x /20xw 0x01161000
0x1161000: 0x00003000 0x00000001 0x00000000 0x00006300
DMA_Debug_Status0
0x1161010: 0x00000000 0x00000000 0x00000000 0x00000000
0x1161020: 0x00000000 0x00000000 0x00000000 0x00000000
0x1161030: 0x00000000 0x00000000 0x00000000 0x00000000
0x1161040: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
3.4 检查过滤等其他设置
如果以上还未收到,检查过两次设置,最好设置为RA接收所有包,
确认DMA的SR是否使能等。
四.发送调试
和接收类似
4.1 检查描述符
检查如下寄存器设置,看TxDesc是否递增
(gdb) x /28xw 0x01161100
0x1161100: 0x00000000 0x00100001 0x00100be1 0x00000000
0x1161110: 0x00000000 0x0200c1200x00000000 0x0200bd00
TxDesc_List
0x1161120: 0x0200c3d00x00000000 0x0200bd20 0x0000003f
TxDesc_Tail Ring_Length
0x1161130: 0x00000001 0x0000c8c3 0x00000000 0x00000000
0x1161140: 0x00000000 0x0200c3d00x00000000 0x0200bd10
TxDesc
0x1161150: 0x00000000 0x0200bd200x00000000 0x0200b710
TxBuffer
0x1161160: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
4.2 确认回写状态
(gdb) p /x tx_desc
$2 = {{des0 = 0x200bdc0, des1 = 0x0, des2 = 0x8000002a, des3 = 0x30000000} }
(gdb)
4.3 确认发送状态
如果以上描述符都正确但是还是没有数据,确认接收是否正在工作
查看DMA_Debug_Status0寄存器
(gdb) x /20xw 0x01161000
0x1161000: 0x00002000 0x00000001 0x00000001 0x00006400
DMA_Debug_Status0
0x1161010: 0x00000000 0x00000000 0x00000000 0x00000000
0x1161020: 0x00000000 0x00000000 0x00000000 0x00000000
0x1161030: 0x00000000 0x00000000 0x00000000 0x00000000
0x1161040: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
4.4 检查发送数据等
检查发送数据是否又64字节以上,可以配置CPC自动添加CRC和填充。
确认DMA的ST使能了发送等。
五.总结
收发驱动实际就是对描述符的操作,需要了解描述符环形结构,软件硬件分别是怎么实用描述符的。另外也需要了解相关寄存器,描述符格式等,了解如何去调试收发过程。
审核编辑 黄宇
-
嵌入式
+关注
关注
5067文章
19008浏览量
302891 -
以太网
+关注
关注
40文章
5371浏览量
171024 -
调试
+关注
关注
7文章
572浏览量
33892 -
驱动开发
+关注
关注
0文章
130浏览量
12061
发布评论请先 登录
相关推荐
评论