VxWorks DM9000 驱动移植(6)

2019-07-13 17:45

111122-1257

NULL, /* pNext */

VXB_DEVID_DEVICE, /* devID */ VXB_BUSID_PLB, /* busID = PCI */ VXBUS_VERSION_3, /* vxbVersion */ ETH_NAME, /* drvName */ ðFuncs, /* pDrvBusFuncs */ //这个是最重要的 ethMethods, /* pMethods */ ethProbe, /* devProbe */

//ethParamDefaults /* pParamDefaults */ }, };

其中,前4个不用动,系统分配 #define ETH_NAME \

而ethMethods,涉及的是方法,我把其中只保留了一项,其实也可以全部屏了。 LOCAL struct vxbDeviceMethod ethMethods[] = {

//DEVMETHOD(miiRead, ethPhyRead), //DEVMETHOD(miiWrite, ethPhyWrite), //DEVMETHOD(miiMediaUpdate,ethLinkUpdate), DEVMETHOD(muxDevConnect, ethMuxConnect), //DEVMETHOD(vxbDrvUnlink, ethInstUnlink), { 0, 0 } };

LOCAL struct drvBusFuncs ethFuncs = {

ethInstInit, /* devInstanceInit */ ethInstInit2, /* devInstanceInit2 */ ethInstConnect /* devConnect */ };

这个结构体就是上面提到的调用关系

2.4. ethInstInit,ethInstInit2,

这2个函数,可以参照其他的驱动,在ethInstInit中 LOCAL void ethInstInit(VXB_DEVICE_ID pDev) {

struct hcfDevice *pHcf;

/* Always use the unit number allocated to us in the hwconf file. */ pHcf = (struct hcfDevice *)pDev->pBusSpecificDevInfo; if(OK != vxbInstUnitSet (pDev, pHcf->devUnit)) DRV_LOG (DRV_DEBUG_LOAD,\ else DRV_LOG (DRV_DEBUG_LOAD,\ return;

}可以完全不动,

26

111122-1257

而ethInstInit2

LOCAL void ethInstInit2(VXB_DEVICE_ID pDev) {

END_DEVICE * pDrvCtrl; #if 1

pDrvCtrl = malloc (sizeof(END_DEVICE));

bzero ((char *)pDrvCtrl, sizeof(END_DEVICE)); pDev->pDrvCtrl = pDrvCtrl; pDrvCtrl->ethDev = pDev; #endif return;

}里面可以任何事情都不做,不过你也可以把这里面的初始化放在后面endload里,有人说6.6的ethInstInit2+endload=5.5的endload。

2.5. ethInstConnect

LOCAL void ethInstConnect( VXB_DEVICE_ID pDev){ DRV_LOG (DRV_DEBUG_LOAD,\ taskDelay(3); ethMuxConnect(pDev,NULL); return; }

可以看出,只是调用了ethMuxConnect。

2.6. ethMuxConnect

LOCAL void ethMuxConnect(VXB_DEVICE_ID pDev,void * unused) {

END_DEVICE *pDrvCtrl; VXB_DEVICE_ID miiDev; char *miiIfName; int miiIfUnit;

DRV_LOG (DRV_DEBUG_LOAD,\ /* Save the cookie. */

pDrvCtrl->ethMuxDevCookie = muxDevLoad (pDev->unitNumber, DM9000EndLoad, \

if (pDrvCtrl->ethMuxDevCookie != NULL)

muxDevStart (pDrvCtrl->ethMuxDevCookie);

if (_func_m2PollStatsIfPoll != NULL)

endPollStatsInit (pDrvCtrl->ethMuxDevCookie,_func_m2PollStatsIfPoll);

27

111122-1257

DRV_LOG (DRV_DEBUG_LOAD,\ taskDelay(3); return; }

调用了2个经典的函数

之后就可以进入DM9000EndLoad了在这里面我们看到了,传输的参数是VXB_DEVICE_ID pDev,这是vxbus新的类型,我的做法是,在设备资源结构体中添加了这几个成员:

2.7.vxbus的 end_device

typedef struct end_device {

END_OBJ end; /* The class we inherit from. */ //add the vxbus's code VXB_DEVICE_ID ethDev; UINT32 ethMask; //这个也可以不用要,但另外2个必须要得 void *ethMuxDevCookie; //end

END_ERR err; UINT IOBase;

int unit; /* unit number */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ long flags; /* Our local flags. */ UCHAR enetAddr[6]; /* ethernet address */

CACHE_FUNCS cacheFuncs; /* cache function pointers */ CL_POOL_ID pClPoolId; /* cluster pool */

BOOL rxHandling; /* rcv task is scheduled */

UCHAR io_mode; /* 0:word, 2:byte */ char tx_pkt_cnt;

char device_wait_reset; UWORD queue_pkt_len;

UCHAR reg0; /* registers saved */ UCHAR nic_type; /* NIC type */

UCHAR op_mode; /* PHY operation mode */

UCHAR mcastFilter[8]; /* multicast filter */ UCHAR dummyBytes[3]; /* dummyBytes, for 32-bit align */ UCHAR txBuf[ETHERMTU + EH_SIZE + 6 + 64 ]; unsigned int io_addr; /**/ unsigned int io_data; } END_DEVICE;

28

111122-1257

2.8. DM9000EndLoad

因为在init2中添加了初始化分配代码,所以,这个函数中可以省去这些 END_OBJ* DM9000EndLoad( char* initString, void *pArg ){ END_DEVICE *pDrvCtrl;

VXB_DEVICE_ID pDev; //主要增加了这1句, UINT32 dataVal; char tmp; int i;

VXB_INST_PARAM_VALUE val; STATUS r; int cnt; pDev = pArg; pDrvCtrl = pDev->pDrvCtrl; //还有这一句,就把VXB_DEVICE_ID和END_DEVICE绑在一起了 …….. }

上面个的这个参数pArg指向的是VXB_DEVICE_ID,而end里是END_DEVICE。 在后续的程序中都可以在开头加上和上面思想类似的两个操作,因为传输的参数类型变了由END_DEVICE到END_OB,如:

static STATUS dm9000Start(END_DEVICE * pEnd ) /* device ID */?end static STATUS dm9000Start( END_OBJ * pEnd ) /* device ID */-?vxbus 而对于这种,可以这样 END_DEVICE * pDrvCtrl; VXB_DEVICE_ID pDev;

pDrvCtrl = (END_DEVICE *)pEnd; pDev = pDrvCtrl->ethDev;

下面的操作就和end的一样了。

2.9.vxbus操作时使用vxbus独有特性探索之hwconf.c

从上面的移植中可以看到,虽然我们用了vxbus,但是我们只是用到了外壳,并没有用到里面一些实际的东西,经过分析,找到了一个可以用到的地方,就是注册中断的时候 原来的注册方法:

intConnect(INUM_TO_IVEC(pDrvCtrl->ivec), (VOIDFUNCPTR)dm9000Int, (int) (pDrvCtrl)); if (result == ERROR){ printf(\ return ERROR; }

printf(\result = intEnable((int)pDrvCtrl->ivec); if (result == ERROR){ printf(\

29

111122-1257

return ERROR; }

新的注册方法:

vxbIntConnect (pDev, 0, dm9000Int, pDrvCtrl); vxbIntEnable (pDev, 0, dm9000Int, pDrvCtrl);

但是要在一个文件中添加资源信息?hwconf.c,找到hcfDeviceList[]数组,在其中添加 #ifdef INCLUDE_DM9000A_VXB_END /* added, 20110820_0926 */ { \#endif

在文件的上面添加

#define INCLUDE_DM9000A_VXB_END #ifdef INCLUDE_DM9000A_VXB_END

#define DM9000A_MAC_BASE 0xd3000000 //资源的基地址 #define INUM_DM9000END0 17 //本次使用的中断号

const struct hcfResource ethDm9000aEnd0Resources[] = { { \ { \ { \ { \ //无需改动 { \ HCF_RES_STRING, { (void *)\ { \ HCF_RES_INT, { (void *)0 } }};

#define ethDm9000aEnd0Num NELEMENTS(ethDm9000aEnd0Resources) #endif

上面的{ \就照应这0?17,你能明白的。

三.移植过程中配到的困难

1.程序的流程,end和vxbus有很大不同,刚开始直接用vxbus,但是不了解,可以的去研究vxbus,导致浪费了时间,最后拐头使用end,成功后,移植到vxbus上。

2.主要是那个swap地方没有弄好,开始没有注意打印信息,后来发现接收和发送的数据全是空的,后来添加上打印信息,找到了错误的地方,但是已经浪费了很多时间 3.对mac和phy的不理解,并且对dm9000的数据手册不熟悉,没有过多的去参看数据手册。 4.对应在这次开发中涉及的重点和疑惑,最终我感觉上面列出的那几个接口函数都相当重要。如果让列出最终要的部分,是最底层的那几个:ior,iow,phy_read,phy_wirte这四个函数,特别是phy的操作,网上也少有涉及的,最后只能手写对它的操作。

30


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

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

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

马上注册会员

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