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

最近论坛中有人问我当时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 的思路。

这个是我个人研发过程中整理的。直接发上来了!如有不妥的地方请包涵!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值