XiangXiangRen
总版主
总版主
  • 注册日期2003-02-22
  • 最后登录2015-09-01
  • 粉丝13
  • 关注0
  • 积分1042分
  • 威望472点
  • 贡献值1点
  • 好评度145点
  • 原创分13分
  • 专家分1分
阅读:2026回复:3

DriverNetworks第四课

楼主#
更多 发布于:2003-03-04 14:10
第四课 关于中断

这也是只用于微端口的。涉及以下几个主题。

1.注册一个中断。

(1).首先,应该在你的工程的Characteristics.h文件中(关于这个文件,我想你在使用向导生成了一个微端口驱动的框架之后,自然就会看见。)声明你对中断相关的回调函数。这里你要使

用一个宏KNDIS_MINPORT_HANDLER.例子如下:

KNDIS_MINIPORT_HANDLER(MyAdapter,DisableInterrupt)
KNDIS_MINIPORT_HANDLER(MyAdapter,EnableInterrupt)
KNDIS_MINIPORT_HANDLER(MyAdapter,HandleInterrupt)
KNDIS_MINIPORT_HANDLER(MyAdapter,Isr)

(2).在你的adapter类中包括一个KNdisInterrupt的数据成员。

class MyAdapter:public KNdisMiniAdapter(
...
KNdisInterrupt m_Interrupt;
...
};

(3).你必须在adapter的Initiazlize()函数中访问一个KNdisXxxResource类来获得系统分配的中断资源。

(4).根据3中得到的信息初始化你的KNdisInterrupt成员。这个过程举例如下:

NDIS_STATUS MyAdapter::Initialize(KNdisMedium& Medium, IN KNdisConfig& Config)
{
  . . .
  //获得资源信息
  KNdisPnpResourceRequest request(Config);
  KNdisResource<CmResourceTypeInterrupt> Int(request);
 
  //确保其可用
  if (!Int.IsValid())
    KNDIS_RETURN_ERROR (NDIS_STATUS_NOT_ACCEPTED);

  //注册你的中断
  m_Interrupt.Initialize(this, Int, NdisInterruptLatched);
  if (!m_Interrupt.IsValid())
    KNDIS_RETURN_ERROR (NDIS_STATUS_RESOURCES);
  . . .
}

(5).在硬件上使能你的中断。这和网卡有关,你得阅读硬件的资料了。这步应该不会很难,我想无非是io操作。io操作怎么做,见上一课。

2.同步工作

任何微端口驱动函数若和其他同在DIRQL层上运行的函数共享任何资源,都必须处理同步问题。这个问题出现在中断相关的两个回调函数Isr()和DisableInterrupt()上。为了同步这些函数,

驱动使用KNdisInterrupt::Synchronize()函数。这个函数将安排指定的函数运行的时候持有一个自旋锁,从来解决同步问题。例子如下:

m_Interrupt.Synchronize(KNDIS_MEMBER_CALLBACK(CardSetMulticast),this);

void MyAdapter::CardSetMulticast()
{
//我们假设这个函数运行于DIRQK,并其中不想被
//Isr()之类的调用打断工作
}

换句话说,使用了Synchronize函数之后,就不必担心CardSetMulicast这个函数会被Isr()或者是DisableInterrupt()这两个函数打断了。

但是在MyAdapter的声明中,还应该有下边的语句:

class MyAdapter:public KNdisMiniAdapter(
...
KNDIS_DECLARE_SYNCHROCALLBACK( MyAdapter,CardSetMulticast);
void CardSetMulticast();
...
);

SYNCHROCALLBACK宏会在adapter类中增加一个静态的成员函数。而系统将会通过这个函数来控制CardSetMulticast()这个函数的运行。

3.最后是注销中断,这样:
m_Interrupt.Invalidate();

关于中断就介绍到这里。具体的使用过程,以后我们看看通过具体的微端口驱动实例就知道了。

下一课介绍如何生成wdm设备对象,以及被动和主动的与应用程序通信。等这些问题解决完,我们将编写一个2000下的简单的中间层驱动做为第一个完整的例子。

最新喜欢:

riririririri
lzwf4
驱动小牛
驱动小牛
  • 注册日期2002-10-10
  • 最后登录2006-06-09
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-03-04 19:42
真是好样的!!!!真是谢谢你了!!!
logincao
驱动牛犊
驱动牛犊
  • 注册日期2002-03-15
  • 最后登录2006-01-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-06-16 22:45
NDIS_STATUS IAdapter::OnReceive
(const KNdisPacket& Original, KNdisPacket& Repackaged)
{
PNDIS_PACKET pOriginal = Original;
PNDIS_PACKET pRepackaged = Repackaged;

Repackaged.CloneUp(Original);

if ( nRetCode == XR_DIRECT_TRANSMIT )
{
ForwardDown(Repackaged);//调用几次就会死掉,不知道为什么?
return NDIS_STATUS_NOT_ACCEPTED;
}
return NDIS_STATUS_SUCCESS;
}

希望高手能给点指点?
QQ:9812343
不在沉默中爆发,就在沉默中死亡
liujun_seu
驱动牛犊
驱动牛犊
  • 注册日期2005-04-11
  • 最后登录2005-05-23
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-04-25 12:11
好贴,谢谢!!!!

[编辑 -  4/25/05 by  liujun_seu]
游客

返回顶部