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

描述

本文转自公众号,欢迎关注

基于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_ListRxDesc_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      0x0200c120      0x00000000      0x0200bd00

TxDesc_List

0x1161120: 0x0200c3d0      0x00000000      0x0200bd20      0x0000003f

TxDesc_Tail                                       Ring_Length                                   

0x1161130: 0x00000001      0x0000c8c3      0x00000000      0x00000000

0x1161140: 0x00000000      0x0200c3d0      0x00000000      0x0200bd10

TxDesc

0x1161150: 0x00000000      0x0200bd20      0x00000000      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使能了发送等。

五.总结

收发驱动实际就是对描述符的操作,需要了解描述符环形结构,软件硬件分别是怎么实用描述符的。另外也需要了解相关寄存器,描述符格式等,了解如何去调试收发过程。

审核编辑 黄宇

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分