最近更换mpc8313的phy芯片,由原来的lxt972Phy更换为DP83849I,在此记录下本人在驱动开发过程中的点滴记录,以备日后查询,基于vxbus的网络驱动,vxBus驱动的注册遵循一致的方法,驱动接口为:
device_method_t dp83849PhyMethods[] =
{
DEVMETHOD(miiModeGet, dp83849PhyModeGet),
DEVMETHOD(miiModeSet, dp83849PhyModeSet),
DEVMETHOD(vxbDrvUnlink, dp83849PhyInstUnlink),
{ 0, 0 }
};
struct drvBusFuncs dp83849PhyFuncs =
{
dp83849PhyDevInstInit, /* devInstanceInit */
dp83849PhyDevInstInit2, /* devInstanceInit2 */
dp83849PhyDevInstConnect /* devInstanceConnect */
};
struct vxbDevRegInfo dp83849PhyDevRegistration =
{
NULL, /* pNext */
VXB_DEVID_DEVICE, /* devID */
VXB_BUSID_MII, /* busID = MII Bus */
VXBUS_VERSION_3, /* busVer */
"dp83849Phy", /* drvName */
&dp83849PhyFuncs, /* pDrvBusFuncs */
dp83849PhyMethods, /* pMethods */
dp83849PhyProbe /* devProbe */
};
void dp83849PhyRegister(void)
{
vxbDevRegister (&dp83849PhyDevRegistration);
return;
}
要编写驱动,主要去实现上面模块中的相关功能,首先编写dp83849PhyProbe,在函数中识别flash的ID,编写其他相关的函数,接下来在sysLib.c中注册系统驱动
#include "Dp83849Phy.c"
void sysHwInit (void)
{
dp83849PhyRegister();
}
接下来,在系统硬件配置hwconf.c中更改phyAddr地址,具体地址参照phy芯片硬件设计
const struct hcfResource motEtsecHEnd0Resources[] =
{
{ "regBase", HCF_RES_INT, { (void *)(CCSBAR + 0x24000) } },
{ "intr0", HCF_RES_INT, { (void *)INUM_TSEC1_TX} },
{ "intr0Level", HCF_RES_INT, { (void *)INUM_TSEC1_TX } },
{ "intr1", HCF_RES_INT, { (void *)INUM_TSEC1_RX } },
{ "intr1Level", HCF_RES_INT, { (void *)INUM_TSEC1_RX } },
{ "intr2", HCF_RES_INT, { (void *)INUM_TSEC1_ERR } },
{ "intr2Level", HCF_RES_INT, { (void *)INUM_TSEC1_ERR } },
{ "phyAddr", HCF_RES_INT, { (void *)14 }},
{ "miiIfName", HCF_RES_STRING, { (void *)"tsecMdio" } },
{ "miiIfUnit", HCF_RES_INT, { (void *)0 } }
};
接下来,由于本次硬件设计采用RMII接口,所以在config.h中更改硬件配置字
/* RMII */
#define HRCW_HIGH_BYTE2 0x24
接下来更改系统MAC寄存器,在vxbEtsecEnd.c中修改下列函数,根据系统硬件配置字设置ETSEC_ECNTRL寄存器的ETSEC_ECNTRL_R100M
LOCAL STATUS etsecLinkUpdate
(
VXB_DEVICE_ID pDev
)
{
switch (IFM_SUBTYPE(pDrvCtrl->etsecCurMedia))
{
case IFM_1000_T:
case IFM_1000_SX:
CSR_SETBIT_4(pDev, ETSEC_MACCFG2, ETSEC_IFMODE_GMII_TBI);
/* R100M is "don't care" for gigE, but clear it anyway */
CSR_CLRBIT_4(pDev, ETSEC_ECNTRL, ETSEC_ECNTRL_R100M);
pDrvCtrl->etsecEndObj.mib2Tbl.ifSpeed = 1000000000;
break;
case IFM_100_TX:
CSR_SETBIT_4(pDev, ETSEC_MACCFG2, ETSEC_IFMODE_MII);
//CSR_SETBIT_4(pDev, ETSEC_MACCFG2, ETSEC_MACCFG2_PREAMBLE_LEN | ETSEC_IFMODE_MII | ETSEC_MACCFG2_PADCRC | ETSEC_MACCFG2_FULL_DUPLEX);
/* Set R100M bit if configured for reduced pin mode RMII */
if (CSR_READ_4(pDev, ETSEC_ECNTRL) & ETSEC_ECNTRL_RMM)
CSR_SETBIT_4(pDev, ETSEC_ECNTRL, ETSEC_ECNTRL_R100M);
//printf("100M ccfg2 = %08x ecntrl = %08x\n", CSR_READ_4(pDev, ETSEC_MACCFG2), CSR_READ_4(pDev, ETSEC_ECNTRL));
pDrvCtrl->etsecEndObj.mib2Tbl.ifSpeed = 100000000;
break;
case IFM_10_T:
CSR_SETBIT_4(pDev, ETSEC_MACCFG2, ETSEC_IFMODE_MII);
//CSR_SETBIT_4(pDev, ETSEC_MACCFG2, ETSEC_MACCFG2_PREAMBLE_LEN | ETSEC_IFMODE_MII | ETSEC_MACCFG2_PADCRC | ETSEC_MACCFG2_FULL_DUPLEX);
/* The R100M bit is always 0 for 10Mbps operation. */
if(CSR_READ_4(pDev, ETSEC_ECNTRL) & ETSEC_ECNTRL_RMM)
CSR_CLRBIT_4(pDev, ETSEC_ECNTRL, ETSEC_ECNTRL_R100M);
//printf("10M ccfg2 = %08x ecntrl = %08x\n", CSR_READ_4(pDev, ETSEC_MACCFG2), CSR_READ_4(pDev, ETSEC_ECNTRL));
pDrvCtrl->etsecEndObj.mib2Tbl.ifSpeed = 10000000;
break;
default:
break;
}
}
值此基本上已经完成驱动程序的修改,由于网络不通,无法加载系统镜像,无法调试,本人的解决办法是,先把vxWorks.bin通过仿真器烧写到flash固定位置,boot上电运行时,再从flash加载到RAM_LOW_ADDR地址处开始运行,这样在网络不通的情况下,可以加载系统镜像进行调试,所以修改bootsehll.c程序,并在autoboot函数中调用:
/*启动时从norflash中拷贝系统镜像到VXWORKS启动地址,然后转到此处执行zhb_2020.12.23*/
void copyVxToRam(void)
{
char *pVxRamAddr = RAM_LOW_ADRS;
char* pVxFlashAddr = FLASH_BASE_ADRS + 0x400000;
int i = 0;
int* pEnterAddr;
FUNCPTR absEntry;
for (i = 0; i < 0x300000; i++)
pVxRamAddr[i] = pVxFlashAddr[i];
pEnterAddr = (int*)pVxRamAddr;
printf("start Vxworks at %08x.....\n", pEnterAddr);
absEntry = pEnterAddr;
(absEntry)();
}
编译boot程序和系统镜像,用仿真器烧写到flash中运行,下面就可以进行调试了。对于phy芯片的调用,可以利用vxBusShow查看设备pDev,然后在shell中用MII_READ,MII_WRITE进行测试
-> vxBusShow
Registered Bus Types:
MII_Bus @ 0x00208d60
Local_Bus @ 0x00206138
Registered Device Drivers:
ppcIntCtlr at 0x00207904 on bus Local_Bus, funcs @ 0x002078f8
VxBus version 2
quiccIntCtlr at 0x00208a2c on bus Local_Bus, funcs @ 0x002089f8
quiccTimerDev at 0x002068ec on bus Local_Bus, funcs @ 0x002068d0
VxBus version 2
motetsec at 0x002026b0 on bus Local_Bus, funcs @ 0x00202584
ns16550 at 0x0020734c on bus Local_Bus, funcs @ 0x002072dc
ns16550 at 0x00207304 on bus PCI_Bus, funcs @ 0x002072dc
ppcDecTimerDev at 0x00208f00 on bus Local_Bus, funcs @ 0x00208ee4
tsecMdio at 0x00208ea4 on bus Local_Bus, funcs @ 0x00208e78
mv88E1x11Phy at 0x00208e38 on bus MII_Bus, funcs @ 0x00208e08
lxt972Phy at 0x00207250 on bus MII_Bus, funcs @ 0x00207244
bcm54xxPhy at 0x00208da8 on bus MII_Bus, funcs @ 0x00208d9c
miiBus at 0x00208d18 on bus PCI_Bus, funcs @ 0x00208cbc
miiBus at 0x00208cd8 on bus Local_Bus, funcs @ 0x00208cbc
plbCtlr at 0x00206160 on bus Local_Bus, funcs @ 0x00206154
dp83849Phy at 0x00202544 on bus MII_Bus, funcs @ 0x00202538
Busses and Devices Present:
Local_Bus @ 0x0023f848 with bridge @ 0x002061a0
Device Instances:
quiccIntCtlr unit 0 on Local_Bus @ 0x00240808 with busInfo 0x00000000
ppcIntCtlr unit 0 on Local_Bus @ 0x00240908 with busInfo 0x00000000
tsecMdio unit 0 on Local_Bus @ 0x00240a08 with busInfo 0x00000000
motetsec unit 0 on Local_Bus @ 0x00240b08 with busInfo 0x00000000
motetsec unit 1 on Local_Bus @ 0x00240c08 with busInfo 0x00000000
ppcDecTimerDev unit 0 on Local_Bus @ 0x00240d08 with busInfo 0x00000000
quiccTimerDev unit 0 on Local_Bus @ 0x00240e08 with busInfo 0x00000000
quiccTimerDev unit 1 on Local_Bus @ 0x00240f08 with busInfo 0x00000000
ns16550 unit 0 on Local_Bus @ 0x00241008 with busInfo 0x00000000
ns16550 unit 1 on Local_Bus @ 0x00241208 with busInfo 0x00000000
miiBus unit 0 on Local_Bus @ 0x00241708 with busInfo 0x0023ff08
miiBus unit 1 on Local_Bus @ 0x00245b08 with busInfo 0x0023ff48
Orphan Devices:
legacy unit 0 on Local_Bus @ 0x00241408 with busInfo 0x00000000
MII_Bus @ 0x0023ff08 with bridge @ 0x00241708
Device Instances:
dp83849Phy unit 0 on MII_Bus @ 0x00245908 with busInfo 0x00000000
Orphan Devices:
MII_Bus @ 0x0023ff48 with bridge @ 0x00245b08
Device Instances:
dp83849Phy unit 1 on MII_Bus @ 0x00245d08 with busInfo 0x00000000
Orphan Devices:
value = 1 = 0x1
对于以太网报文的测试,我们可以增加测试程序,从中断中捕获报文分析,测试以太网发送报文
LOCAL int etsecEndEncap
(
ETSEC_DRV_CTRL * pDrvCtrl,
M_BLK_ID pMblk
)
{
ETSEC_DESC * pDesc = NULL, * pFirst;
ETSEC_TX_FCB * pFcb;
M_BLK_ID pCurr, pStart;
UINT32 firstIdx, lastIdx = 0;
struct ether_header * eh;
int used = 0, i;
int j = 0;
// printf("send net data ......\n");
//for (j = 0; j < pMblk->mBlkHdr.mLen; j++)
// printf("%02x ", pMblk->mBlkHdr.mData[j]);
// printf("\n");
}
测试以太网接收报文
void usrPrintNet(ST_INT port, ST_VOID* pM)
{
char gsBuf[L2_DATA_MSG_SIZE];
int i = 0;
M_BLK_ID pMblk = (M_BLK_ID)pM;
memcpy(gsBuf, pMblk->mBlkHdr.mData, pMblk->mBlkHdr.mLen);
if (g_debug_net == 1)
{
printf("revCnt = %d\n", gsvEthInfo[port].allPacketCount);
for (i = 0; i < pMblk->mBlkHdr.mLen; i++)
printf("%02x ", gsBuf[i]);
printf("\n");
}
}
LOCAL void etsecEndRxHandle
(
void * pArg
)
{
usrPrintNet(pDrvCtrl->etsecDev->unitNumber,pMblk);
}
注意:如果你的驱动程序在boot和系统镜像中存在两份,务必保持驱动程序的一致性,否则可能出现奇怪的现象,调试中发现以太网发送中断不能进,最后发现是boot和vxWorks中的驱动程序不一致导致的,折腾了两天,我也是醉了