网友 gaozhenjiang-002 提出来的问题如下:
我在看你的网卡驱动时,对于board_eth_rcv这个函数没看太懂,尤其是下面这段
SetRegPage(1);
RxPageEnd = inportb(CURR);
LWIP_DEBUGF(RTL8019_DEBUG, ("RTL8019's CURR = %d \r\n",RxPageEnd));
SetRegPage(0);
RxPageBeg = rBNRY+1;
if(RxPageBeg>=RPSTOP)
RxPageBeg = RPSTART;
outportb(0x22, BaseAddr);
outportb(0, RSAR0);
outportb(RxPageBeg, RSAR1);
outportb(4, RBCR0);
outportb(0, RBCR1);
outportb(0xa, BaseAddr);
RxLength = inportw(RWPORT);
RxStatus = RxLength&0xff;
RxNextPage = RxLength>>8;
RxLength = inportw(RWPORT);
RxLength += RxLength&1;
那么我就针对这段代码做一个简单的解释,如果有不明白的地方,请继续提问。
首先我先介绍一下void SetRegPage(U8 PageIdx)这个函数
void SetRegPage(U8 PageIdx)
{
U8 temp;
temp = inportb(BaseAddr);
temp = (temp&0x3b)|(PageIdx<<6);
outportb(temp, BaseAddr);
}
这个你要是对8019这颗芯片有了解的话,我想你应该能看的明白,它主要实现的功能是:设置8019选中页地址
RxPageEnd = inportb(CURR);
上面这句话的意思是:读出当前接收缓冲区的地址指针
LWIP_DEBUGF(RTL8019_DEBUG, ("RTL8019's CURR = %d \r\n",RxPageEnd));
这句话是为了调试的时候方便查看各个寄存器而写的调试语句,可以不去考虑。
SetRegPage(0);
RxPageBeg = rBNRY+1; //rBNRY 初始值 0x4C
if(RxPageBeg>=RPSTOP) //RPSTOP = 0x80
RxPageBeg = RPSTART; //RPSTART = 0x4C
outportb(0x22, BaseAddr); //启动RTL8019
outportb(0, RSAR0); //RSAR0、RSAR1 设置远程DMA起始地址
outportb(RxPageBeg, RSAR1);
outportb(4, RBCR0); //RBCR0、RBCR1 设置远程DMA数据字节数
outportb(0, RBCR1);
outportb(0xa, BaseAddr); //启动DMA读操作
这些都是针对8019这颗芯片寄存器做的一些设置,具体参数你可以参考datasheet,这里我就不做详细的介绍了。
RxLength = inportw(RWPORT);
RxStatus = RxLength&0xff;
RxNextPage = RxLength>>8;
RxLength = inportw(RWPORT);
RxLength += RxLength&1;
这个就是读取数据的长度,8019芯片存放数据长度是放在两个寄存器里面,你需要读两次 ,才能读出来争取的结果。
所以我感觉对于上面的程序,都是针对8019这个芯片的一些基本的设置和操作。你可以在看代码前,先去看看这颗芯片的资料,对这个芯片的寄存器有所了解,然后再去试着看程序,读懂程序。