VxWorks DM9000 驱动移植(5)

2019-07-13 17:45

111122-1257

RxLen = tmp1 + (tmp2<<8); //读取数据长度 }

Else //world模式,是这个程序的默认模式,为2字节,程序进入这里 { outb(dev->io_addr, 0xf2); RxStatus = SWAP16(inb(dev->io_data)); //这个16为2交换很重要 RxLen = inb(dev->io_data); }

if( RxLen < 0x40) //下面3个if都是错误检测 {

DRV_LOG (DRV_DEBUG_RX, \ GoodPacket = 0; }

if( RxLen > DM9000_PKT_MAX ) {

DRV_LOG (DRV_DEBUG_RX, \ dm9000Reset( dev ); dm9000Config( dev ); return 2; }

if( RxStatus & 0xbf) {

GoodPacket = 0;

/*if( RxStatus & 0x100 ) fifo error */ /*if( RxStatus & 0x200 ) crc error */ /*if( RxStatus & 0x8000 ) length error */

DRV_LOG (DRV_DEBUG_RX, \ }

/* Move data from DM9000 */ skb->len = 0;

if( GoodPacket && (skb != NULL) ) { /* good packet*/ skb->len = RxLen; rdptr = skb->pData;

/* Read received packet from RX SARM */ if (dev->io_mode == 1) { /* Byte mode */

for( i=0; i

rdptr[i]=dm9k_inb(dev->io_data); }

else

{/* Word mode */ //程序会进入这个地方 tmplen = (RxLen + 1) / 2; for( i = 0; i < tmplen; i++ ) {

21

111122-1257

data_tmp=inb(dev->io_data); ((unsigned short *)rdptr)[i] = SWAP16(data_tmp); } }

return 0; }

else //这就是坏包,处理方式是只是用临时变量来接收,但不提交。 { /* bad packet*/

/* Without buffer or error packet */ if( dev->io_mode == 1 ) {

/* Byte mode */

for( i = 0; i < RxLen; i++ ) tmp1=dm9k_inb(dev->io_data); } else {

/* Word mode */

tmplen = (RxLen + 1) / 2; for( i = 0; i < tmplen; i++ ) (unsigned short )tmp3 = SWAP16(inb(dev->io_data)); }

return 1; } }

DRV_LOG (DRV_DEBUG_RX, \ return 1; }

上面这个函数解析很清楚,在调试的时候可以在里面添加打印信息,打印接收包的数据,看是否和抓包工具抓到的相同,由于是在中断中处理的,打印信息时要用log_msg()函数。

2-8. dm9000McastAdd dm9000MCastDel dm9000McastGet dm9000PollSend dm9000PollRcv等解析

这几个函数比较简单,并且在数据传输上一般不过多处理,可以不写(函数内部写空)或者使用原先的,而对于endEtherAddressForm,endEtherPacketDataGet,endEtherPacketAddrGet这3个函数完全不用动,内部调用的是系统函数。不过dm9000PollSend dm9000PollRcv函数需要在进行处理一下,还得和sent,Rcv差不多,我把代码贴在下面

static STATUS dm9000PollSend( END_DEVICE *pDrvCtrl,M_BLK_ID pMblk) {

int len; u_short stat; PKT skb; int oldv;

22

111122-1257

DRV_LOG (DRV_DEBUG_POLL_TX, \ /* TODO - test to see if tx is busy */

stat = dm9000StatusRead (pDrvCtrl); /* dummy code */ if ((stat & (DM9000_TINT|DM9000_TFULL)) == 0) return ((STATUS) EAGAIN); /* TODO - transmit packet */

len = netMblkToBufCopy (pMblk, (char*)(pDrvCtrl->txBuf), NULL); len = max (len, ETHERSMALL); skb.len = len;

skb.pData = (char*)pDrvCtrl->txBuf;

oldv = intLock();

dmfe_start_xmit( &skb, pDrvCtrl );//可以看到,内部仍然调用了dmfe_start_xmit() intUnlock( oldv );

/* Bump the statistic counter. */

END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* Free the data if it was accepted by device */ netMblkClFree (pMblk);

DRV_LOG (DRV_DEBUG_POLL_TX, \ return (OK); }

//可以看出,poolsend和send没有区别,我有点怀疑我基于原先的包是不是有问题 static STATUS dm9000PollRcv( END_DEVICE *pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk ) /* ptr to buffer */ {

u_short stat; char* pPacket; int len;

PKT skb;

DRV_LOG (DRV_DEBUG_POLL_RX, \ stat = dm9000StatusRead (pDrvCtrl);

/* TODO - If no packet is available return immediately */ if( !(stat&DM9000_RXRDY) ) {

DRV_LOG (DRV_DEBUG_POLL_RX, \ return (EAGAIN); }

pPacket = NULL; /* DUMMY CODE */ len = 64; /* DUMMY CODE */

/* Upper layer must provide a valid buffer. */

if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) {

DRV_LOG (DRV_DEBUG_POLL_RX, \ return (EAGAIN);

23

111122-1257

}

/* TODO - Check packet and device for errors */

END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);

/* TODO - Process device packet into net buffer */ skb.len = 0;

skb.pData = pMblk->m_data;

if( dmfe_packet_receive( &skb, pDrvCtrl ) ) //调用了dmfe_packet_receive() {

DRV_LOG (DRV_DEBUG_POLL_RX, \ return (EAGAIN); }

/* bcopy (pPacket, pMblk->m_data, len); */

pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */ pMblk->mBlkHdr.mLen = len; /* set the data len */ pMblk->mBlkPktHdr.len = len; /* set the total len */ /* TODO - Done with packet, clean up and give it to the device. */

DRV_LOG (DRV_DEBUG_POLL_RX, \ DRV_LOG (DRV_DEBUG_POLL_RX, \ return (OK); }

可以看出,poollRcv和普通的Rcv也没太大的区别,只是普通的是要自己申请Cluster和Mblk等,而pooll是上层直接传递下来了。

二.Dm9000-vxwork6.6-vxbus模型移植

1. 前言:

Dm9000-vxwork6.6-vxbus模型移植在我的移植方法里面基本上没有太多的设计vxbus的操作,也是我对vxbus不太了解,在这次的移植过程中,基本上只是用了vxbus的外壳,没做其他事情。Vxbus和end的注册方法不一样,end是在configNet.h中添加资源和入口函数,而vxbus是在usrAppinit.c中添加自己的入口函数(我的方法是这样的),而注册方法也不是很一样,依次设计:ethRegister()?vxbDevRegister ((struct vxbDevRegInfo *)ðDevPlbRegistration)? drvBusFuncs ethFuncs?ethInstInit?ethInstInit2?ethInstConnect?

ethMuxConnect?muxDevLoad?muxDevStart.最后2个函数应该是大家比较熟悉的,在end模型中也是这样调用的。而设计的资源文件为:hwconf.c,可以使用,也可以不使用,后续将会设计到,下面涉及源码

24

111122-1257

2.涉及代码

2-1.usrAppinit.c的void usrAppInit(void)函数

void usrAppInit(void) {

#ifdef USER_APPL_INIT USER_APPL_INIT; /* for backwards compatibility */ #endif flashStart(); ethRegister(); //这就是入口函数 #if 1 taskDelay(5); //下面这几个是网卡初始化,驱动写好后添加的网卡设置 ipAttach(0,\ taskDelay(3); ifconfig(\ taskDelay(3); ifconfig(\ taskDelay(3); ifconfig(\#endif }

2.2. ethRegister

void ethRegister(void) { map_op(); //这个函数对应于end中的dm9000ConfigInit(),不多介绍 vxbDevRegister ((struct vxbDevRegInfo *)ðDevPlbRegistration); DRV_LOG (DRV_DEBUG_LOAD,\ taskDelay(3); return; }

vxbDevRegister ((struct vxbDevRegInfo *)ðDevPlbRegistration) 会把 ethDevPlbRegistration给注册进去

2.3.ethDevPlbRegistration

LOCAL struct vxbPlbRegister ethDevPlbRegistration = {

{

25


VxWorks DM9000 驱动移植(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:指数函数、对数函数图像交点问题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: