您的位置:首页 > 其它

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

2010-12-30 11:02 537 查看
最近论坛中有人问我当时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

的思路。

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