Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76946
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-11 10:56
文章分类

全部博文(35)

文章存档

2016年(2)

2015年(33)

我的朋友

分类: C/C++

2015-06-02 10:15:11

九.RTL8019AS,RTL8029AS如何接收一个数据包(1)

分类: RTL8019 3148人阅读 评论(0)  举报
 我们在上面谈到了网卡的ram的结构,网卡ram是以256字节为一页,是按页存储的结构,16位的ram的地址的高8位又叫页码.
  网卡的16k的ram地址从0x4000-0x7fff,从页0x40到页0x7f,一共有64页.这64页被用来接收和发送数据包用.


  一般把前面的12页用来存放发送的数据包,后面的52页用来存放接收的数据包.
  当然你也可以配置成前面52页用来接收,而后面的12页用来发送.
  或者你也可以不使用那么多的缓冲区,比如只用32页来做为缓冲区,前面的6页用来发送,接下来的26页用来接收,而把空出来的32页给单片机使用,用来存储别的数据.
  那么哪些页被用来做接收缓冲区由两个寄存器决定:
Pstart(page start register)
Pstop(page stop register)

  PSTART,PSTOP是16位ram地址的高8位,也就是页码.
  举个例子:
PSTART=0x4c
PSTOP =0x80
  这时网卡将使用0x4c00-0x7fff的ram来存储接收到的数据包.PSTOP是0x80而不是0x7f,PSTOP的意思是,从该页开始的页不能做为 接收缓冲区.而PSTART的意思是从这一页开始做为接收缓冲区.
因此PSTART=0x4c ,PSTOP=0x7f+1=0x80,PSTOP被设置为(最后一页的页码+1).
  再如:
PSTART=0x40
PSTOP=0x60
  那么网卡使用0x4000-0x5FFF做为接收缓冲区. 
  而我的程序的设置是PSTART=0x4c PSTOP=0x80
  而页0x40--0x4b共12页做为发送数据缓冲区,为什么用12页,是因为最大的一个数据包是1514字节+4字节校验.一个最大的数据包需要6页=256*6=1536字节.
  12页可以放两个最大的包.我们把前6页0x40--0x45称为发送缓冲1,接下来的6页0x46--0x4B称为发送缓冲2.
  这两个发送缓冲的作用是:
  用户可以将数据包放在发送缓冲1,然后启动发送.发送的过程中,如果用户还有数据包要发,那么这时把要发的数据包放在发送缓冲2(一边发送,一边把下一包放到缓冲区里),等到发完发送缓冲1的数据包就可以马上启动发送缓冲2的数据包.这样可以不断地进行发送数据.
  我们设置了接收缓冲区之后,那么接收到的第一个数据包放在哪里呢?这由CURR决定.
  控制接收缓冲区的有两个寄存器CURR,BNRY.CURR是网卡写缓冲区的指针,指向此时要写的页.
  BNRY是读指针,指向用户已经读走的页. 
 
  那么要知道网卡正在写哪一个字节的数据,读取CLDA1,CLDA0的值就知道了.
  那么如何初始化CURR,BNRY这两个指针呢?
  初始化的时候使BNRY=CURR-1页,
  例如:
CURR=0x4d
BNRY=0x4c

  要注意的是:如果
CURR=0x4c(第一个接收页)
那么BNRY=0x7f(最后一个接收页)
  写成语言就是:
  BNRY=CURR-1;
  if(BNRY<0x4c)BNRY=0x7f; 
这就是两者的初始化的关系式.

  初始化CURR=0x4d,表示第一个收到的数据包将存放在0x4d00地址开始的缓冲区.
初始化CURR=0x4c,表示第一个收到的数据包将存放在0x4c00地址开始的缓冲区.
CURR只初始化一次,以后都不用再去修改它.

  我的设置是CURR=0x4d.
  网卡收到一个数据包,假如是一个短数据包,只要一页就可以存储的,那么这时候
CURR将会被加一.CURR将等于0x4d+1=0x4e.
  假如需要两页来存储,那么CURR将等于0x4d+2=0x4f
如果CURR等于结束页PSTOP,也就是CURR>0x7f时,CURR将被重置成等于PSTART=0x4c.
CURR是网卡内部自己控制的.用户不需要干预.
  网卡存储一定是按页存储,不满一页,也使用一页,下一包将用下一页开始存储. 
  举个例子;
CURR=0x4f
BNRY=0x4e
  这时收到一个数据包

这是一个典型的ARP应答包,数据包发往52:54:ab:3d:8e:2c,发送者的网卡地址为
00:d0:09:68:f7:1e ,类型为0806
假设我的网卡地址是52:54:ab:3d:8e:2c,那么可以收到该包
这时
CURR=0x50
BNRY=0x4e 
  那么收到一包之后BNRY=CURR-2,而不是BNRY=CURR-1,也就是说两个指针差了两页,而不是一页.也就是说当CURR , BNRY 两个指针差2页或2页以上时,表示网卡收到新的数据包.(检查是否有新的数据包要用到这个关系,没有新的数据包时,两者指针只差一页).
 ,数据包只有60个字节的数据,那么网卡将用CURR指向的页0x4f来存储该包数据.
  存储内容如下:
0x4f00:015040005254AB3D8E2C00D00968F71E
0x4f10:0806000108000604000200D00968F71E
0x4f20:C0A800015254AB3D8E2CC0A800070000
0x4f30:00000000000000000000000000000000
0x4f40:492E24C8
  我们可以看到前面和后面都加了一些东西,中间的才是数据.
  共加了8个字节的内容(共用了68个字节). 
  那么前面的4个字节的含义为:
 
  前面的4个字节为:01504000
  第一个字节0x01为接收的状态,也就是RSR(接收状态寄存器的值)
  该字节Receive Status含义:
  那么根据上面的标志位的定义,0x01=0000 0001B,也就是标志位PRX=1 ,表示这个数据包接收良好,没有错误.CRC=0,表示校验正确.PHY=0,表示这不是广播数据包.
  第2个字节0x50 Next Packet Pointer,是一个指针,表示下一个数据包将存储在0x50页开始的地址0x5000.事实上等于此时的CURR=0x50.
  第3和第4是接收的长度.表示该数据包的长度.这里是0x4000,要注意的是长度的高位和低位是颠倒的:
Receive Byte Count1=0x00
Receive Byte Count0=0x40
  长度应该是0x0040=64字节.60字节是内容,4字节校验. 
  最后面的4个字节 492E24C8就是CRC校验码.


阅读(1416) | 评论(0) | 转发(0) |
0

上一篇:Rtl8019 for S3C44B0 驱动程序源码解析

下一篇:没有了

给主人留下些什么吧!~~