您的位置:首页 > 其它

wince下Dm9000A驱动调试总结----转自巴乔 .

2012-05-04 13:13 267 查看
最近论坛中有人问我当时Dm9000A驱动调试问题,刚好最近有点问题重新整理个文档发上来,和各位分享下,有什么不对的或者疑问的地方请留言。

Dm9000a
驱动总结

Dm9000a 是最近比较纠结的一个问题,其实去年早应该把这个问题提到议事日程上了,但是项目没有计划,工作东一头西一头,把这个事业就忘记了。实在是替自己感到悲哀。

最近这网卡怎么了呢?因为采购的几个片子出现了 VID 和 PID 错误的情况。而我记得去年网卡驱动调试的时候也是换了块 dm9000 就好了,当时为了赶进度,没有进一步分析。刚好今年回来有好几个地方进一步认识的过程遇到了问题。下面总结下以备后用。

DM9000 是 DAVICOM 公司的一个网卡芯片。封装是 LQFP48 pin 的,使用电源为 3.3 ,最大耗用电流为 92ma ,和 mcu 连接有两种模式及 8bit 和 16bit ,内置了 auto-mdi-x 功能 10/100m PHY 支持多种连接模式,支持 eeprom ,可以存放系统信息。支持 tcp/ip 加速功能、

Dm9000a 在使用中有几个注意的地方:

1.CS 口接的是 nGCS 几,因为这个片选信号直接影响了我们 IO 映射的时候的区域( BANKCON )我们的硬件 nCS 接的应该是 mGCS3 ,那根据 2440 的 memory map 应该是 0x18000000 。

2.CMD 口接的是地址几号线,如果用的是 A1 那么在做 IOBASE +偏移地址的时候需要加 2 ,如果是 A2 (大多数的板子是这个)那么就是需要加 4 。

3. INT 口接的是系统中断那个中断脚,我们的硬件接的是 EINT2 ,那么用的就是系统中断

dm9000a 在 wince 下面的驱动。

首先分析下 dm9000a 在 wince 中的源码。 从 dm9000.def 文件中可以看到 dm9000 的驱动程序( dm9000.dll ) exports 的函数只有 DriverEntry 。从名字上也可以看出这是该 dll 文件入口。

下面详细看下这个入口函数(在 driver.cpp 中实现):在这个函数中主要有一个 NdisMInitializeWrapper() ,这个函数中有很多回调函数 MiniportInitialize , MiniportReset , MiniportInterruptHandler , MiniportISRHandler , MiniportQueryInformation , MiniportSetInformation , MiniportSend )。这些函数在驱动中已经实现好了。在这里还有一个
NdisMRegisterMiniport () 函数。 This function registers an NIC or intermediate driver's Miniport_* entry points and name with the NDIS library when the driver initializes 。就是用刚才初始化的那个结构体注册。在 public/common/oak/drivers/netsamp/passthru
/miniport.c 中微软提供了一系列 Miniportxxxx 函数的实现范例。 help 中对 MiniportInitialize 的解释是:
This function is a required function that sets up a network adapter, or virtual network adapter, for network I/O operations, claims all hardware resources necessary to the network adapter in the registry, and allocates resources
the driver needs to carry out network I/O operations.

接下来就是 MiniportInitialize 了。在其中有 NIC_DRIVER_OBJECT 类的初始化,以及该类的 EDriverInitialize 函数调用,在此函数中全面展开了 dm9000 的所有初始化操作。主要是通过 DeviceEntry() 这个函数来实现(这个函数实现在 dm9000.cpp 文件中),在 DeviceEntry 这个函数中只做了一件事: new 了一个 C_DM9000 类的实例并 return 。这里小弟通过调试信息发现在 MiniportIntialize()
中做很多工作, DeviceSetDefaultSettings();DeviceSetEepromFormat();DeviceRetriveConfigurations(hconfig);EDeviceValidateConfigurations() 等等。在这里我的驱动已经读取了 dm9000 的 ID 。

C_DM9000::EDeviceInitialize

[dm9000: Chip signature is 90000A46

DM9000 EDriverInitialize EDeviceInitialize

DM9000 EDeviceRegisterInterrupt

+OALIntrEnableIrqs(1, 0x8201ef20)

+BSPIntrEnableIrq(-1).

DM9000 EDriverInitialize EDeviceRegisterInterrupt

C_DM9000::DeviceOnSetupFilter

C_DM9000::DeviceStart

C_DM9000::DeviceEnableInterrupt

<DM9:--MiniportInitialize> 这段是 MiniportIntialize 函数最后的些信息。当初始化完成后有个 DriverStart ()。这里程序主动权基本都在 c_DM9000 的类里了。俺网上牛的文章在 DeviceEnableInterrupt ()启动中断后,接下来就是无休止的等待,接收,发送了。

源码分析完了,我们看看还有几个特别的地方,第一注册表

[HKEY_LOCAL_MACHINE/Comm/DM9CE]

"DisplayName"="DM9000A/9010 ISA Fast Ethernet Adapter"

"Group"="NDIS"

"ImagePath"="dm9isa.dll"

[HKEY_LOCAL_MACHINE/Comm/DM9CE/Linkage]

"Route"=multi_sz:"dm9ce1"

[HKEY_LOCAL_MACHINE/Comm/DM9CE1]

"DisplayName"="DM9000A/9010 ISA Fast Ethernet Adapter"

"Group"="NDIS"

"ImagePath"="dm9isa.dll"

[HKEY_LOCAL_MACHINE/Comm/Tcpip/Linkage]

"Bind"="dm9ce1"

[HKEY_LOCAL_MACHINE/Comm/DM9CE1/Parms]

"BusNumber"=dword:0

"BusType"=dword:0

"XmitBuffer"=dword:20

"RecvBuffer"=dword:20

"IrqNumber"=dword:2

;"IoAddress"=dword:18000300

"MACAddress" =hex:20,04,09,18,00,07

[HKEY_LOCAL_MACHINE/Comm/DM9CE1/Parms/TcpIp]

"EnableDHCP"=dword:0

"UseZeroBroadcast"=dword:0

"DefaultGateway"="192.168.1.1"

"LLInterface"=""

"UseZeroBroadcast"=dword:0

"IpAddress"="192.168.1.33"

"Subnetmask"="255.255.255.0"

"DNS"="192.168.1.1"

;"WINS"="192.168.1.1"

注册表要注意的地方就是红色部分了。
"IrqNumber"=dword:2

;"IoAddress"=dword:18000300 这个地方的 IrqNumber 夜就是系统中断号,我们用的是中断号 2 吗?所以这个等于 2 ,这里再多讲下,当时调试时遇到中断不产生的情况。可以用示波器看硬件上中断是否产生。而去年的那块片子就是没有产生硬件中断害的我调试了一周。还有这个地方的 2 是系统中断号 2 ,那如果我是中断号 9 呢??是不是就是 9 呀?错了!这个应该更具
wince 系统中的逻辑中断号和硬件中断号的关联,在 s3c2440a_intr.h 中 #define IRQ_EINT9
37 的定义。那么我们这个 "IrqNumber"=dword:2 就应该是
"IrqNumber"=dword:0x25 (37) 。
IoAddress 这个又是个比较纠结的问题。首先这个值其实应该是 0x18000000+0x300 ,这个 0x18000000 很好理解就是前面说的 cs 口的接法。也就是说这个是根据硬件来的。我们接的是 nGCS3 那就是 0x18000000 。那为什么加上 0x300 。说实话本人能力有限至今还不是很清楚。 悲哀中。。。

下面我们看下源码中的一个数组

CONFIG_PARAMETER g_szDm9ConfigParams[] =

{

{ CID_CONNECTION_TYPE, -1, NDIS_STRING_CONST("ConnectionType") },

{ CID_SLOT_NUMBER, -1, NDIS_STRING_CONST("SlotNumber")},

{ CID_BUFFER_PHYSICAL_ADDRESS, 0, NDIS_STRING_CONST("BufferPhysicalAddress")},

{ CID_TXBUFFER_NUMBER, 0x20, NDIS_STRING_CONST("XmitBuffer")},

{ CID_RXBUFFER_NUMBER, 0x10, NDIS_STRING_CONST("RecvBuffer")},

{ CID_ADAPTER_NUMBER, 0, NDIS_STRING_CONST("AdapterNumber")},

{ CID_IO_BASE_ADDRESS, 0x18000300, NDIS_STRING_CONST("IoAddress")},

{ CID_IO_RANGE, 0x10, NDIS_STRING_CONST("IoRange")},

{ CID_IRQ_NUMBER, 0x2, NDIS_STRING_CONST("IrqNumber")}, { -1,-1,NULL}

};

这个地方红色部分也就是和注册表中一样的。必须和注册表一样。

上述的工作完成后。 Dm9000a 在 wince5.0 下的驱动基本完成了。但是目前遇到某些芯片读取 VID 和 PID 和文档不一样的情况。还不知道什么情况,等找到原因在总结一次吧!这次总结关键是理清调试 dm9000a 的思路。

这个是我个人研发过程中整理的。直接发上来了!如有不妥的地方请包涵!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: