VxWorks DM9000 驱动移植(4)

2019-07-13 17:45

111122-1257

return (y); }

2-7.dm9000int

dm9000int是在dm9000Start函数中被注册,里面主要处理recive中断和sent中断(这个主要是对计数器进行--,没别的涉及数据的操作)。

static void dm9000Int( END_DEVICE *pDrvCtrl ) /* interrupting device */ {

UCHAR stat, reg_save, isr_status, nsr_status; /* tx_status, */ UCHAR TX_comple_status;

/* Save previous register address */ DM9000_IN_ADDR( reg_save );

iow(pDrvCtrl, 0xff, DM9000_REGFF_OFF ); /*temp*/ stat = dm9000StatusRead (pDrvCtrl);

//INT_RECIVE_DEBUG(\ /* Clear ISR status */

isr_status=ior(pDrvCtrl,0xfe);

//INT_RECIVE_DEBUG(\ iow(pDrvCtrl, 0xfe, isr_status );

DRV_LOG (DRV_DEBUG_INT, \ /*

* enable interrupts, clear receive and/or transmit interrupts, and clear * any errors that may be set. */

/* Have netTask handle any input packets */

if( (isr_status & 1 )&&(stat & DM9000_RXON) ) {

DRV_LOG (DRV_DEBUG_INT, \ if ( pDrvCtrl->rxHandling != TRUE ){ pDrvCtrl->rxHandling = TRUE; /*dm9000HandleRcvInt(pDrvCtrl);*/ #ifdef DRV_DEBUG g_IntrNum++;

#endif //添加接收中断处理函数

netJobAdd ((FUNCPTR)dm9000HandleRcvInt, (int)pDrvCtrl,0,0,0,0); } }

/* TODO - handle transmit interrupts */ if( isr_status & 2 ) { //发送中断处理

DRV_LOG (DRV_DEBUG_INT, \

16

111122-1257

4, 5, 6);

TX_comple_status=ior(pDrvCtrl,0x1); if (TX_comple_status & 0xc){ /* One packet sent complete */ pDrvCtrl->tx_pkt_cnt--; //处理一个发送中断 INT_DEBUG(\ /* Queue packet check & send */

if (pDrvCtrl->tx_pkt_cnt > 0){ //处理第二个中断 iow(pDrvCtrl, 0xfc, pDrvCtrl->queue_pkt_len & 0xff ); iow(pDrvCtrl, 0xfd, (pDrvCtrl->queue_pkt_len >> 8) & 0xff ); iow(pDrvCtrl, 0x2, 0x01 ); } } } intRet:

/* Re-enable interrupt mask */

iow(pDrvCtrl, 0xff, DM9000_REGFF ); /* Restore previous register address */ DM9000_OUT_ADDR( reg_save ); }

注意事项,其中对发送中断时的2步处理是考虑到中断可能有时候没有来得及相应(情况很多),这时已经发送了2个包了,而此时就要对2次包进行处理了,也就是说发送了2个包,但是只响应了一次中断。

接收中断处理函数netJobAdd ((FUNCPTR)dm9000HandleRcvInt, (int)pDrvCtrl,0,0,0,0);分析: static void dm9000HandleRcvInt( END_DEVICE *pDrvCtrl ) /* interrupting device */ {

char* pData; int i;

unsigned short tmp3;

pDrvCtrl->rxHandling = TRUE;

DRV_LOG (DRV_DEBUG_INT, \ while (OK==dm9000PacketGet (pDrvCtrl)) { if(dm9000Recv (pDrvCtrl, (char*)NULL ) == ERROR) break; }

pDrvCtrl->rxHandling = FALSE; }

pDrvCtrl->rxHandling就是用来标记接收中断是否处理完成的,就是一个接收中断标志函数中涉及dm9000PacketGet()和dm9000Recv(),先看dm9000PacketGet() STATUS dm9000PacketGet( END_DEVICE *pDrvCtrl ) {

UCHAR rxbyte;

rxbyte=ior(pDrvCtrl,0xf0); rxbyte=ior(pDrvCtrl,0xf0);

/* packet ready to receive check */ if( rxbyte == DM9000_PKT_RDY )

17

111122-1257

{

DRV_LOG (DRV_DEBUG_LOAD, \ return OK; }

DRV_LOG (DRV_DEBUG_LOAD, \ return ERROR; }

此函数主要检测dm9000接收寄存器是否准备好 下面分析dm9000PacketGet()函数

static STATUS dm9000Recv( END_DEVICE *pDrvCtrl, /* device structure */ char* pData ) /* packet to process */ {

char* pClusterData; M_BLK_ID pMblk; char* pNewCluster; CL_BLK_ID pClBlk; PKT skb; int i;

DRV_LOG (DRV_DEBUG_LOAD, \#ifdef DRV_DEBUG g_RecvNumError++; #endif

pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId); if (pNewCluster == NULL) {

DRV_LOG (DRV_DEBUG_RX, \ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; }

/* Grab a cluster block to marry to the cluster we received. */

if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) {

netClFree (pDrvCtrl->end.pNetPool, pNewCluster);

DRV_LOG (DRV_DEBUG_RX, \ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; }

/** OK we've got a spare, let's get an M_BLK_ID and marry it to the * one in the ring.*/

if ((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) {

netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); netClFree (pDrvCtrl->end.pNetPool, pNewCluster);

DRV_LOG (DRV_DEBUG_RX, \ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);

18

111122-1257

goto cleanRXD; }

END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); /* align IP header at 32-bit boundary, this is reqired by VxWorks ** TCP/IP stack*/

pClusterData = (char*)((((unsigned long)pNewCluster + 1) & (~1)) | 2 ); /* move packet from Ethernet on-board SRAM to the mbuf pre-allocated ** in system memory */

skb.pData = pClusterData;

skb.len = 0;

//下面的这个函数是重点

if( dmfe_packet_receive( (PKT*)(&skb), pDrvCtrl ) ) {

mBlkFree (pDrvCtrl->end.pNetPool, pMblk); netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); netClFree (pDrvCtrl->end.pNetPool, pNewCluster);

DRV_LOG (DRV_DEBUG_RX, \ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; }

/* Join the cluster to the MBlock */

netClBlkJoin (pClBlk, pNewCluster, skb.len, NULL, 0, 0, 0); netMblkClJoin (pMblk, pClBlk);

pMblk->mBlkHdr.mData = pClusterData; pMblk->mBlkHdr.mLen = skb.len;

pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = skb.len;

#if 0 //用来验证数据是否接收出来,用来和抓包工具的数据进行比照 for(i=0;i<(skb.len +1 )/2;i++){ INT_RECIVE_DEBUG(\ if(((i+1) % 20)==0) INT_RECIVE_DEBUG(\}

INT_RECIVE_DEBUG(\#endif

/* make the packet data coherent */

END_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, skb.len); /* Call the upper layer's receive routine. */

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

DRV_LOG (DRV_DEBUG_INT, \#ifdef DRV_DEBUG g_RecvNum++;

19

111122-1257

g_RecvNumError--; #endif

return (OK); cleanRXD:

return (ERROR); }

对于上面这个函数中的一些步骤,无需多管,这个函数是vxworks封装好的一个标准接收处理函数,思路是依次创建Cluster,clblk,mblk,然后把这3者给联系起来,而把接收得数据使用这个函数dmfe_packet_receive(),把dm9000缓冲池中的数据取出来,放到Cluster里面,然后把mblk的指针返回给上层mux层,接收驱动就算完成了。下面分析dmfe_packet_receive()函数:

static int dmfe_packet_receive( PKT *skb, END_DEVICE *dev ) {

UCHAR tmp1,tmp2; UWORD tmp3; UCHAR rxbyte; UCHAR *rdptr;

UWORD i, RxStatus, RxLen, GoodPacket, tmplen; int oldv;

UWORD RxStatus_tmp,data_tmp;

DRV_LOG (DRV_DEBUG_NO, \ rxbyte=ior(dev,0xf0); rxbyte=ior(dev,0xf0);

/* Status check: this byte must be 0 or 1 */

if( rxbyte > DM9000_PKT_RDY )//仍然是检测是否准备好,这个地方可以去掉 {

iow(dev, 0x05, DM9000_REG05_OFF); /* Stop Device */ iow(dev, 0xff, DM9000_REGFF_OFF); /* Stop Device */ DRV_LOG (DRV_DEBUG_RX,\ dm9000Reset( dev ); dm9000Config( dev ); return 2; }

/* packet ready to receive check */ if( rxbyte == DM9000_PKT_RDY ) {

/* A packet ready now & Get status/length */ GoodPacket = 1;

if( dev->io_mode == 1 ) //字节处理模式,和下面单字节接收对应 { tmp1=ior(dev,0xf2); tmp2=ior(dev,0xf2);

RxStatus = tmp1 + (tmp2 << 8); //读取状态 tmp1=ior(dev,0xf2); tmp2=ior(dev,0xf2);

20


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

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

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

马上注册会员

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