当前位置:首页 > 嵌入式 > 嵌入式软件
[导读]Windows9x/NT及2000下中断驱动程序的统一化处理

Windows以其友好的图形用户界面,使得它不仅成为办公管理首选的操作系统,也日益受到工程技术人员的关注,逐渐取代DOS而成为主流的工程应用控制平台。但是,Windows系统为了保证平台的安全与完整性,对系统底层操作采取了屏蔽的策略,利用VxD将用户与硬件隔离开来。 在Windows9x(95、97、98)下,用户如果需要实现对硬件的中断、DMA或存储空间物理地址等资源进行访问,必须通过设备驱动程序来进行硬件操作;而在WindowsNT下,即使是简单的I/O操作,也需要编写驱动程序方能与硬件打交道。

  Windows操作系统的主流目前是Windows9x和WindowsNT,而已经推出的Windows2000是以WindowsNT为主要框架的。由于Windows9x和WindowsNT两者在系统核心上有质的不同,所以即使对于同样一个硬件,在两者下的驱动程序也有很大的区别。因此,一般而言,需要针对不同的操作系统编写不同的驱动程序。

  兼容X86指令的微机CPU运行时有4个优先级,Ring0~Ring3。操作系统与驱动程序运行在Ring0级,可以对所有硬件资源进行控制;用户程序运行在Ring3级,对资源控制受到一些限制。而对于Ring0级的驱动程序而言,它的编写和调试通常需要对操作平台的运行机制有较深的了解,从而要求程序开发者掌握Windows9x、NT及Windows2000的内核管理机制,对于开发人员来讲这有相当大的难度。 在这里,笔者使用了美国Jungo公司出品的WinDriver工具包,利用其绕过了对操作系统内核的学习掌握这个难点,并且在不更改程序代码的前提下,完成了在多个操作系统下对硬件中断的一致处理,很方便地解决了硬件与程序在不同系统下的移植问题。

1 Windows下硬件中断的管理机制

  在多任务的环境里,硬件设备中断管理程序是非常重要的系统级程序。它不仅要把硬件发生的中断时间传给相应的驱动程序,还要允许某些设备驱动程序处理它们特殊的中断服务。在Windows平台下,VPICD(虚拟可编程中断控制器)就是这样的硬件设备管理程序,它负责管理所有的硬件中断时间。VPICD通过一个缺省机制触发驻留在VM(虚拟机)内的中断处理函数。它完全允许VxD根据其需要而重载中断处理函数。PC机的硬件中断需要确定硬件中断的IRQS(中断申请号),对一个特定的IRQ中断源,VPICD或提供缺省的中断处理函数,或允许其它VxD重载中断处理函数。

  VPICD提供的缺省中断处理是:首先置中断禁止,再触发相应VM中的中断处理函数。因为VPICD实现了对PPIC(物理可编程中断控制器,如8259中断控制器)的虚拟化,所以当VM中的中断处理函数发送EOI(中断处理结束指令)时,VPICD即对PPIC发EOI指令。最后,VPICD控制处理函数的返回操作,恢复中断,并置VM状态为VM进入中断前的状态。当VPICD对某些中断的缺省处理不够充分或则不太合适时,就需要亲手编写一个VxD,在其中实现中断的虚拟化。VxD将决定如何处理硬件中断以及如何调用VM中的中断处理函数。

  下面将要详述的WinDriver对中断处理作了很好的封装,将对VPICD和VM的控制和处理以及某些特殊的驱动要求封装在经过严格调试的WinDriver.vxd和WinDriver.sys中,并对调用驱动程序的API(应用编程接口)函数进行了系统集成,让使用者直接面对用高级语言集成好的类库和函数接口,从而大大降低了程序开发的难度,缩短了开发周期。

2 WinDriver工具包简介

  WinDriver是美国Jungo公司出品的用于编写驱动程序的一种工具包,主要针对ISA/PCI插卡,4.2版本以后还提供了USB的开发工具。最新版本4.40版所编写的程序兼容性十分强大,包括了Windows9x、Windows NT、Windows2000、Windows CE、Linux、Solaris(Intel)、VxWorks (Intel) 、OS/2等诸多操作平台。WinDriver主要包括一个WinDriverWizard、一个WinDriver发行包、多个公用程序以及大量的例程。

  (1)WinDriverWizard

  这是一个友好的Windows向导界面。运行WinDriverWizard,它可以让你立即接触到硬件而不用写一句有关的代码。这种便利来自于它的自动检测功能。对于ISA插卡,用户可以直接利用它来读写卡上的内存、I/O地址、寄存器以及侦听中断。对于PCI插卡,除了上面的基本功能外,还可以方便地读写PCI的配置信息。

  在此之后,通过选择“GenerateCode”选项,WinDriverWizard会为你的插卡产生基本的程序代码。4.2版本以后还提供了多种编程语言选择,几乎包括了所有流行的编程语言,如VC4?觸VC6、Borland C++Builder3?觸4、Pascal、Delphi、Linuxmake、Solariesmake等等。这就让用户不必去学新的编程语言,很容易地直接上手。[!--empirenews.page--]

  (2)公用程序

  WinDriver提供了pci_scan、pci_dump、pci_diag、isapnp_scan、wdreg、wddebug等多个公用程序。pci_scan可以给出安装的PCI卡及系统为它们分配资源的列表;pci_dump则负责得到已安装的PCI卡的系统配置信息;pci_diag兼有两者功能;isapnp_scan为用户指出了即插即用的ISA插卡的有关信息;wdreg为用户提供了修改注册表的工具,可以用来方便地安装用户编写的程序;wddebug则是一个用于调试用户程序的有效工具。

  (3)大量例程

  WinDriver提供了许多例程,使用者可以利用它们来产生自己驱动程序的基本框架。与此同时,在WinDriver提供的在线帮助里,可以查到许多WinDriver封装好的功能函数。这些函数能够方便地实现中断处理、DMA传输、I/O操作、内存映射以及即插即用等功能。而且对于常用的PCI桥芯片,如PLX9050、PLX9060、PLX9080、AMCC5923、AMCC5933、V3、ALTERA、GT64等等,提供了特定的检测程序和相应的API函数,大大减轻了用户的编程难度。

3 WinDriver的驱动程序编程模式原理

  WinDriver编程有两种模式。一种模式是用户模式,这种模式实际上不是让用户来编驱动程序,而是利用软件自身提供的驱动程序Windrvr.vxd和Windrvr.sys,用户所面对的只是驱动程序给出的相应功能接口;即使是这个接口,也用高级语言进行了很好的封装,使用十分容易。另一种模式是“核心插入”模式用KernelPlugIn方式进行编程,形成.vxd和.sys文件,这是真正意义上的驱动程序。当用户有特殊的速度要求时,后者是较好的方式。这种方式最快,据Jungo公司的评测报告中讲,可以在一秒钟内处理100,000次中断,笔者在硬件中尝试了一下10,000次中断/秒,获得了成功。

  对于对操作系统内核了解不多的开发者,用户模式无疑是非常值得推荐的。本文重点即是放在这方面。使用用户模式,这里要特别注意以下几个功能函数:

  (1) WD_Open()——获得驱动程序(指Windrvr.vxd或Windrvr.sys)的句柄,它实际上是调用了CreateFile()API函数,在程序开始时必须调用;

  (2) WD_Close()——释放驱动程序的句柄,它实际上是调用了CloseHandle()API函数,在程序结束时必须调用;

  (3) WD_CardRegister()——负责插卡登记项目的建立和资源分配,资源包括I/O操作、内存分配、中断处理等。它调用了DeviceIOControl()API函数;

  (4) WD_CardUnRegister()——负责插卡登记项目的删除和资源释放,与前者相对应,也调用了DeviceIOControl()API函数;

  (5) InterruptThreadEnable()-中断使能,使能后可以接收中断信号,调用Interrupt_handler()函数对中断进行相应处理。在其中集成了CreateThread()API函数;

  (6) Interrupt_handler()-中断处理函数,开发者在这里加入自己对硬件的控制代码。

  (7) InterruptThreadDisable()-使中断无效的函数,屏蔽掉中断信号,不再对其进行处理。在其中集成了WaitForSingleObject()和CloseHandle()这两个API函数。

4 具体示例

  下面给出一个用户模式的具体示例。用VisualC++6编译调试通过,在Windows9x和WindowsNT下系统运行良好,在Windows2000下也能够稳定运行。windrvr.h和windrvr.vxd、windrvr.sys由软件提供,这里就不详述。对于Windows9x系统,注意将windrvr.vxd拷贝到C:WindowsSystemVmm32目录下;对于WindowsNT系统,注意将windrvr.sys拷贝到C:WINNTSystem32DRIVERS目录下。Listen_Interupt.C程序框架如下,该程序实现了中断12的截获:[!--empirenews.page--]

  Listen_Interupt.c源程序

 

  //应包含的头文件

  #include ″../../include/windrvr.h″

  #include ″../../include/windrvr_int_thread.h″

  #include

  //设置自己的中断号,这个例子为中断12

  enum {MY_IRQ=12};

  //建立全局的WinDriver句柄

  HANDLE hWD;

  //建立中断结构

  WD_INTERRUPT Intrp;

  Static char line[256];

  //中断处理过程,你可以用pData来传递从InterruptThreadEnable()得来的信息

    VOID interrupt_handler(PVOID pData)

  {

       //在这里加入你要做的中断处理代码

       printf(″截获中断的数目为%dn″,Intrp.dwCounter);

  }

  //主函数

  int main()

  {

       WD_CARD_REGISTER cardReg;//建立插卡登记项目的一个实例

       WD_VERSION verBuf;

       hWD=WD_Open();//获得驱动程序的句柄

  if(hWD==INVALID_HANDLE_VALUE)

  {

       printf(″打开WINDRVR出现错误!n″);

       return0;

  }

  BZERO(verBuf);

  WD_Version(hWD,&verBuf);

  if(verBuf.dwVer

  {

       printf(″WINDRVR版本不正确,这里需要的版本为:%dn″,WD_VER);

       return0;

  }

  //初始化cardReg,这是程序的重要部分

  BZERO(cardReg);

  cardReg.Card.dwItems=1;

  cardReg.Card.Item[0].item=ITEM_INTERRUPT;

  cardReg.Card.Item[0].fNotSharable=True;

  cardReg.Card.Item[0].I.Int.dwInterrupt=MY_IRQ;

  cardReg.Card.Item[0].I.Int.dwOptions=1;

  cardReg.fCheckLockOnly=True;[!--empirenews.page--]

  WD_CardRegister(hWD,&cardReg);

  if(cardReg.hCard==0)

  {

              printf(″无法锁定设备!″);

  }

  else

  {

              HANDLE thread_handle;

              BZERO(Intrp);

              Intrp.hInterrupt=cardReg.Card.Item[0].I.Int.hInterrupt;

              Intrp.Cmd=NULL;

              Intrp.dwCmds=0;

              Intrp.dwOptions=0;

              printf(″开始中断线程n″);

              //这里调用WD_IntEnable(),并且建立一个中断处理的线程

              if(!InterruptThreadEnable(&thread_handle,hWD,&Intrp,&interrupt_handler,NULL))

              {

                     printf(″中断使能失败!n″);

              }

              else

              {

                     //callyourdrivercodehere

                            printf(″敲回车键不再进行中断截获n″);

                     gets(line);

                     //这里调用禁止截获中断的函数:WD_IntDisable()

                     InterruptThreadDisable(&thread_handle);

                     }

                     //释放所登记的资源

                     WD_CardUnregister(hWD,&cardReg);

                     }

                     //删除驱动程序的句柄。

                     WD_Close(hWD);

                     return0;

  }

  按照本文给出的技术方案,掌握必要的Windows编程技术,即可以成功地实现Windows环境下对硬件中断的直接控制,很方便地在不同系统下进行移植。实践证明,这种方法是切实可行,行之有效的。

 

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭