板卡驱动 c VxD驱动程序编写方法与实例

合集下载

DriverStudio培训教程

DriverStudio培训教程

驱动开发网之 DriverStudio教程(由北京朗维赞助) 由北京朗维计算机应用技术公司赞助编写的DriverStudio教程,此教程全面详细地讲述了以DriverStudio为开发工具编写设备驱动程序和核心层程序的技术与技巧。

包括完全的库参考手册与开发技巧的中文版本。

DriverStudio培训教程△前言△DriverStudio开发工具包介绍△DriverStudio套件包的安装与运行环境设置△使用Vtoolsd写我们的VXD驱动△VXD的调试技术△Vtoolsd运行库函数介绍△一个Vtoolsd开发的文件保护程序例子△一个Vtoolsd开发的硬件板卡驱动例子△VXD驱动程序的安装及应用层对它的调用△DriverWork介绍△DriverWork核心运行类库介绍△生成我们的第一个WDM驱动程序△WDM驱动程序的调试技术△开发一个硬件板卡的WDM驱动△开发一个过滤器驱动程序△10分种开发一个USB驱动(USB版版主倾情奉献)△inf文件的编制及WDM驱动程序的安装△应用层对WDM的调用△DriverNetWork介绍△与网络有关的运行库△开发一个可以实用的防火墙例子△其它实用工具介绍△DriverStudio附带例子程序介绍前言鉴于国内开发人员迫切需要学习驱动开发技术,而国内有关驱动开发工具DriverStudio的资料很少,大家在开发过程中遇到很多问题却没处问,没法问.而这些问题却是常见的,甚至是很基础的问题。

有感于此,本站联合北京朗维计算机应用公司编写了本教程。

本教程的目的是让一个有一些核心态程序编写经验或对系统有所了解的人学习编写驱动程序。

当然,本教程不是DDK中有关驱动方面内容的替换,而只是一个开发环境的介绍和指导。

学习本教程,你应该能熟练地使用本套工具编写基本的驱动程序。

当然如果你想能顺利地编写各种各样的驱动的话,你应该有相关的硬件知道和系统核心知识并且要经过必要的训练才能胜任。

VC编写驱动方法

VC编写驱动方法

VC编写驱动方法编写VC驱动方法在VC开发中,驱动方法是一种非常重要的处理方式。

它可以帮助程序员更好地管理代码,增加代码的可读性以及可维护性。

下面将介绍一些常用的VC驱动方法。

1.初始化方法初始化方法是驱动程序启动时最先调用的方法,在这个方法中可以进行一些初始化操作,比如初始化一些全局变量、分配内存等。

在VC中,一般使用WinMain函数或者OnInitDialog方法来实现初始化。

2.事件处理方法事件处理方法是用来处理操作系统或者用户输入的事件的方法,比如鼠标点击事件、键盘按键事件等。

在VC中,可以通过添加事件响应函数来实现事件处理方法。

在这些方法中,可以根据事件的类型和参数来做出不同的反应。

3.获取数据方法获取数据方法是用来从外部或者数据库中获取数据的方法,比如从文件中读取配置信息、从网络中获取数据等。

这些方法可以根据需要进行适当的封装,例如提供参数来指定从哪个文件中读取配置信息,或者提供一个回调函数来处理网络数据。

4.更新数据方法更新数据方法是用来向外部或者数据库中写入数据的方法,比如向文件中写入日志信息、向数据库中插入新的记录等。

这些方法可以根据需要进行适当的封装,例如提供参数来指定要写入的文件或者数据库的位置,或者提供一个回调函数来处理写入的结果。

5.计算方法计算方法是用来进行一些数学或者逻辑计算的方法,比如计算两个数的和、判断一个数是否为质数等。

在VC中,可以将这些方法放在一个单独的类或者模块中,方便调用。

另外,为了增加代码的可读性,可以添加注释来说明计算的过程和结果。

6.绘制方法绘制方法是用来在屏幕上绘制图形或者文本的方法,比如绘制一个按钮、一个文本框等。

在VC中,可以通过使用GDI+库来实现绘制方法。

在这些方法中,可以使用各种图形和绘制函数来实现特定的绘制效果。

7.保存方法保存方法是用来将程序状态或者数据保存到磁盘或者其他设备中的方法,比如保存程序的配置信息、保存用户输入的数据等。

c语言驱动代码怎么写代码驱动电脑的基本步骤

c语言驱动代码怎么写代码驱动电脑的基本步骤

c语言驱动代码怎么写代码驱动电脑的基本步骤C语言驱动代码:如何编写代码驱动电脑的基本步骤在计算机科学中,驱动程序是指用于控制硬件设备的程序,它充当了计算机操作系统与硬件之间的桥梁。

C语言是一种功能强大的编程语言,用于编写高效的驱动程序。

本文将介绍编写C语言驱动代码的基本步骤。

1. 确定驱动目标在编写驱动程序之前,需要明确驱动的目标是什么。

驱动可以是针对不同硬件设备的,如打印机、鼠标等。

在本文中,我们将以一个简单的案例来说明,即键盘驱动程序。

这个驱动程序将使计算机能够识别和响应键盘输入。

2. 学习设备相关文档在编写驱动程序之前,需要详细了解被驱动设备的特点和功能。

这通常通过查阅设备的技术文档或供应商提供的开发者文档来实现。

对于键盘驱动程序,需要查阅键盘的通信协议和按键编码等信息。

3. 编写初始化代码初始化代码用于准备驱动程序与设备之间的通信。

键盘驱动程序通常需要打开设备的接口,并设置设备的初始状态,以便能够接收按键输入。

这可能涉及到与设备进行握手的通信过程。

4. 编写中断处理程序键盘驱动程序需要能够实时响应用户的按键操作。

为了实现这一点,中断处理程序被用来处理从键盘设备发出的中断信号。

中断处理程序负责解析按键事件,并根据用户的输入进行相应的操作。

例如,当用户按下某个键时,中断处理程序可以将该按键的字符发送给操作系统或其他应用程序。

5. 实现设备控制功能驱动程序还可以提供一些额外的设备控制功能,以便于用户与设备进行交互。

例如,在键盘驱动程序中,可以实现控制LED灯的功能,通过向设备发送控制指令,来控制键盘上的灯光。

6. 进行测试和调试编写完驱动程序后,需要进行测试和调试,以确保其能够正常工作。

这可以通过连接设备并运行相应的应用程序来完成。

在测试过程中,需要验证驱动程序是否能够正确地解析键盘输入,并对其做出正确的响应。

在编写C语言驱动代码时,还有一些编码规范和最佳实践需要遵循。

例如,应避免使用与已有库函数或全局变量相同的命名,以防止命名冲突。

VC编写驱动方法

VC编写驱动方法

VC编写驱动方法编写驱动方法是嵌入式系统开发中的重要环节,本文将介绍编写驱动方法的一般流程和常用技巧。

驱动程序是一种特殊的软件,其功能是控制硬件设备,使之按照预期工作。

在嵌入式系统中,驱动程序通常编写在硬件抽象层(HAL)之上,为操作系统或应用程序提供访问与控制硬件设备的接口。

编写驱动程序一般可以按照以下步骤进行:1.了解硬件设备:在编写驱动程序之前,首先需要对所要驱动的硬件设备有一个基本的了解。

包括硬件设备的型号、接口方式、寄存器设置等。

这些信息对于驱动程序的编写非常重要。

2.选择合适的编程语言:驱动程序可以使用多种编程语言来编写,包括C、C++、汇编等。

一般而言,C语言是编写驱动程序的首选,因为它具有良好的可移植性和较高的执行效率。

3.初始化驱动程序:驱动程序的初始化是一个非常关键的步骤,它需要完成一些必要的设置和初始化操作,以确保驱动程序能够正常工作。

一般而言,初始化包括设备的注册、中断处理程序的注册等。

4.编写设备控制接口:驱动程序的核心功能是控制硬件设备,实现对设备的读写、配置等操作。

因此,需要编写一系列的设备控制接口函数,包括打开设备、关闭设备、读取数据、写入数据等。

5.处理中断和异常:在嵌入式系统中,硬件设备常常会产生中断和异常,驱动程序需要捕获并正确处理这些中断和异常。

一般而言,可以使用中断处理程序来处理硬件设备产生的中断,将中断源的状态读取并进行相关操作。

6.进行测试和调试:编写驱动程序之后,需要进行测试和调试。

可以通过一些软件工具和硬件设备来验证驱动程序的正确性和稳定性。

测试的内容包括设备读写、配置修改等常见操作。

编写驱动程序时1.模块化设计:将驱动程序划分为多个模块,每个模块负责一个具体的功能。

模块化设计有助于提高代码的可读性和可维护性,同时也方便进行单元测试和调试。

2.数据结构和算法选择:根据不同的硬件设备和应用场景,选择合适的数据结构和算法来实现驱动程序。

例如,对于需要高效处理数据的设备,可以使用缓冲区来进行数据的存储和处理。

VXD

VXD
模式。
另 一 些 娄 的 信 息 其 本 身 并 不 复 杂 只
们 要 运 行 的 vx d 程 序 的 名 字 例 如
x t s ,然 后 在 该 子 键 对 应 的 右 边 窗 是 要 为 实 现 的 不 同 功 能 构 造 程 序 处 理 V d e t 口 中建 立 一 个 值 为 0 的 = 进 制数 据 0 代 码 设 备 描 述 块 f h D i e e e e D — T v c 顼 ,并 命 名 为 S a t t r ,再 创 建 一 个 字 符 串数 据 项命 名为 Sa 1Vd 值 为 ” : L t x 赋 c C
维普资讯
圣 哥质量
启动 佬与位嚣 表巷
Y D驱 动 程 序 开 发 及 P I 口板 卡 设 计 X C 接
o n e l D ve opm e o X D nd PCI ntf rV a
姜 明 . 郭 全 咂 , 黄 跃 敏 ( 京 自动测 试技术 研究所 .北 京 1 08) 北 0 O 8
1 X 驱动程序的构架和开发环境 、VD
1. x 驱 动程 序 的 框 架 结构 1vd
Vd 动程 序是 运行 于 rn O 权  ̄ 驱 ig 特
等级 的 应用 程 序 具 有 内 己 的 程 宁 框
・ 系统初 始化 类 信息 ・ 系 统 结 束 类 信 息 ・ V M初 始 化 类 信 息 ・ v 结 束 类 信 岜 M ・v M状 态 变 化 类 信 息 ・ 线程 初始 化类 信息 ・ 线程 结束 类信 息 ・ 其 它 类 信 息
s r p o L c 简 称 D B c 1t rB ok D )是 v M调 1 2 V d驱 动 程 序的 加 载 过 程 M . x 用 P d 旬 柄 .也就 是一 个 数据 结 构, x 的 芑 向 V M 供 了 舍 有 V d 标 识 和 指 向 M 提 x 的

PCI 在WIN98NT 环境下驱动程序的开发

PCI 在WIN98NT 环境下驱动程序的开发

PCI在WIN98/NT环境下驱动程序的开发蔡 勇摘要: 本文简要介绍了编写PCI驱动程序的一般过程、Windows环境下驱动程序的种类和现在比较流行的几种PCI驱动程序的开发环境,并详细介绍了PCI在WIN98/NT环境下驱动程序的开发方法。

关键词:驱动程序 PCI VtoolsD DDK一.概述随着IT行业日新月异的飞速发展,PCI总线以其不可比拟的优势逐渐取代ISA总线成为占主导地位的总线类型,ISA总线逐渐会完成其历史使命而退出历史舞台。

在工业控制及军品测试领域中,市场上现有的PCI板卡类型还不能满足许多应用的要求。

例如ARINC-429总线MIL-1553B总线等的PCI板卡就要做硬件专门设计,而对应驱动程序的开发就成为使用这些板卡的关键之一。

本文简要介绍了编写PCI驱动程序的一般过程、Windows环境下驱动程序的种类和现在比较流行的几种PCI驱动程序的开发环境,并详细介绍了PCI在WIN98/NT环境下驱动程序的开发方法。

二.PCI驱动程序开发的一般过程从广义上来说,设备驱动程序就是控制硬件设备的一组函数。

PCI驱动程序的开发,就是取得PCI板卡所占用的各种资源(内存、端口、中断和DMA等),并提供给用户一条可以访问这些资源的途径。

对于所有的PCI板卡,基本上都可以用下面的方法来开发驱动程序。

2.1取得PCI板卡所占用的资源。

无论是ISA板卡还是PCI板卡,用户要使用它,就必须能访问它所占用的各种资源。

对于ISA板卡,它所占用的资源是定死的,可以直接访问;而PCI板卡是即插即用的,它占用的所有资源都是由系统分配的,要想访问这些资源,就必须先取得这些资源。

2.2建立起上层应用程序和底层驱动程序之间的映射关系。

因为在WIN98和NT等操作系统下,各种资源的访问对用户来讲是透明的,用户不能在上层应用程序里直接访问硬件资源,只能靠底层驱动程序来访问它。

因此用户要实现对板卡的控制,就必须在应用程序和底层驱动程序之间架起一座桥梁,来实现应用程序和驱动程序之间的联系。

用VtoolsD开发WIN9X下的PCI设备驱动程序VXD

用VtoolsD开发WIN9X下的PCI设备驱动程序VXD

收稿日期:2001-03-07 作者简介:武安河(1966-),男,河南沁阳人,信息工程大学讲师,硕士,主要研究方向为通信与信息系统。

用VtoolsD 开发WIN9X 下的PCI 设备驱动程序VX D武安河1,邰铭2,杨柳3(11信息工程大学基础部,河南郑州 450002;21信息工程大学安全学院,河南郑州 450002;31焦作教育学院, 河南焦作 454000)摘要:介绍在WI NDOWS 95/98环境下,用VtoolsD 工具包开发PCI 设备驱动程序VX D 的方法。

关键词:PCI 设备驱动程序;VX D ;即插即用;内存;中断;DM A 中图分类号:TP319 文献标识码:A 文章编号:1671-0673(2001)03-0050-031 前言在Windows 9X 下,如果要访问硬件设备、处理硬件中断、实现DM A 操作,就需要用到设备驱动程序VX D ,开发即插即用(PnP )的PCI 接口卡设备,更是这样。

VX D 是虚拟设备驱动程序(Virtual Device Driv 2er )的缩写,运行在系统保护层(Ring0层),它可以完成各种各样的系统物理层的访问。

如何开发设备驱动程序VX D ?美国Vireo S oft 2ware 公司推出了VtoolsD 开发工具包。

VtoolsD 要比DDK 编程工具方便、容易。

在Windows 9X 下安装一个PCI 设备,用户首先要将卡安装上,然后启动Windows 系统。

系统的枚举器将自动识别新设备,设备安装器将提示用户插入一张设备安装盘。

设备安装盘包括一个设备驱动程序,一个设备信息文件(I NF 文件),和一些可选的设备应用程序或诊断程序。

I NF 文件是Windows 9X 即插即用标准的重要部分。

它为设备安装器提供了一个显示给用户的设备描述和一个设备驱动程序的安装脚本。

这个脚本包括:安装盘上驱动程序的名称,驱动程序应该复制到的目录,以及在驱动程序安装时必须生成或修改的注册表入口。

此类板卡编程方法比较复杂,根据说明书上面说明我们可

此类板卡编程方法比较复杂,根据说明书上面说明我们可

在论坛中经常有人提出关于研华工业用控制板卡的VC编程方法.此类板卡编程方法比较复杂,根据说明书上面说明我们可以采用两种编程方法,一种是自己编写控制各种寄存器代码进行数据的采集和输出,另外一种就是利用他封装的DLL的方法访问相应的函数进行完成.为了节省时间提高开发效率,当然使用第二种方法了.我们可以根据研华光盘里面提供的例子进行修改就可以完成了.正文1:A/D板编程实例(型号:PCL1754,通道:64)//定义一个结构体变量保存64通道的DI信息struct tagSYSTEMSTATE{int nState;//DI状态BOOL bState;//是否为数字量接点};//初始化里面启动线程进行板卡的采集工作void CMy11View::OnInitialUpdate(){CView::OnInitialUpdate();m_Info = new tagSYSTEMSTATE[64];for(int i=0;i<64;i++){m_Info.nState = 0;m_Info.bState = FALSE;}unsigned int nDummy;m_pThread=(HANDLE)_beginthreadex(NULL,0,Main_Thread_DI,this,CREATE_SUSPENDED,&nDummy);//开辟DI线程if (!m_pThread)TRACE(_T(" Couldn't start a thread\n"));elseResumeThread(m_pThread);}//转线程进行采集的循环工作UINT WINAPI CMy11View::Main_Thread_DI(LPVOID pParam)//控制DI线程{CMy11View * pView=(CMy11View *)pParam;while(1){pView->ptDeviceReadDIByte();pView->nVal++;pView->ShowMsg();Sleep(10);}return 0;}//下面是调用DLL进行信号采集工作void CMy11View::ptDeviceReadDIByte(){SHORT gnNumOfDevices;LONG DriverHandle = (LONG)NULL;USHORT gwChannel;static PT_DioReadPortByte ptDioReadPortByte;USHORT gwValue;gnNumOfDevices = 1;DRV_DeviceOpen(gnNumOfDevices,//板号0;(LONG far *)&DriverHandle);for(gwChannel = 0; gwChannel < 8;gwChannel ++){ptDioReadPortByte.port = gwChannel;//////////0-7通道号ptDioReadPortByte.value = (USHORT far *)&gwValue;DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPortByte);gwValue=gwValue&0x00ff;/////////////////for(int j=0;j<8;j++){if( (gwValue & (1<0)m_Info[gwChannel*8+j].nState = 1;elsem_Info[gwChannel*8+j].nState = 0;}}DRV_DeviceClose((LONG far *)&DriverHandle);}//下面将个通道点状态在界面输出,这里各位可以根据实际情况进行修改void CMy11View::ShowMsg(){CDC *pDC;pDC = GetDC();CRect rect;GetClientRect(&rect);CString strText;CBrush pNewBrush,*pOldBrush;pNewBrush.CreateSolidBrush(RGB(128,128,255));pOldBrush=pDC->SelectObject(&pNewBrush);pDC->FillRect(&rect,&pNewBrush);COLORREF *oldCol;oldCol=(COLORREF *)pDC->SetTextColor(RGB(255,0,0));pDC->SetBkColor(RGB(128,128,255));pDC->TextOut(10,10,"采集模拟点显示信息:");strText.Format("线程采集程序运行了%d次",nVal);pDC->TextOut(10,35,strText);for(int i=0;i<64;i++){strText.Format("第%.2d个结点的信息是:%d",i+1,m_Info.nState); int nHeight= (i/4)*25;int nWidth = (i%4)*180;pDC->TextOut(10+nWidth,70+nHeight,strText);}pDC->SelectObject(&oldCol);pDC->SelectObject(&pOldBrush);pNewBrush.DeleteObject();pDC->DeleteDC();}//到此,DI输入编程基本结束,输出方法类似,这里不在进行叙述了.程序模拟演示界面可以见下://AD大致情况入DI,相应的主要不同在于板卡的采集程序,大致见下: void CADDemoView::ptDeviceReadADByte(){USHORT gwChannel = 0; // input channelfloat gwValue;SHORT gnNumOfDevices;static PT_AIConfig ptAIConfig; // structure for AIConfig tablestatic PT_AIVoltageIn ptAIVoltageIn; // structure for AIVoltageIn table static PT_DeviceGetFeatures ptDevFeatures;static DEVFEATURES DevFeatures; // structure for device featuresgnNumOfDevices = 0;DRV_DeviceOpen(gnNumOfDevices,//板号0;(LONG far *)&DriverHandle);ptDevFeatures.buffer = (LPDEVFEATURES)&DevFeatures; ptDevFeatures.size = sizeof(DEVFEATURES);DRV_DeviceGetFeatures(DriverHandle,//句标市柄(LPT_DeviceGetFeatures)&ptDevFeatures);for(gwChannel = 0; gwChannel < 32;gwChannel ++){Sleep(1);ptAIVoltageIn.chan = gwChannel;ptAIVoltageIn.gain = 0;ptAIVoltageIn.TrigMode = 0; // internal trigger ptAIVoltageIn.voltage = (FLOAT far *)&gwValue;DRV_AIVoltageIn(DriverHandle,(LPT_AIVoltageIn)&ptAIVoltageIn); m_Info[gwChannel].fState = gwValue;}DRV_DeviceClose((LONG far *)&DriverHandle);}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

摘要VxD是virtual['və:tʃuəl] X driver的简写,即虚拟设备驱动程序。

x代表各种设备的名字,如虚拟键盘驱动程序(vkd),虚拟鼠标驱动程序(vmd)等等。

VxD程序是硬件成功初始化的途径。

记得dos程序认为它们拥有系统的一切,当它们在虚拟机中运行时,Windows需要给它们一个实机器的替身。

VxD程序就是这些替身。

VxD程序通常虚拟一些硬件设备,所以,例如当一个dos 程序认为它在同键盘通讯时,实际是虚拟键盘驱动程序在和dos程序通讯。

一个VxD程序通常控制真正的硬件设备并对该设备在各个虚拟机之间的共享进行管理。

尽管如此,并不是说每个VxD程序必须和一个硬件设备相连。

虽然VxD程序是用来虚拟硬件设备的,但是我们也可以把VxD程序看作是在第0级别的dll。

例如,如果你需要做一些只有在第0级别才能做的工作,你就可以编一个VxD程序来为你完成这个工作。

这样,由于此VxD程序并没有虚拟任何设备,你就可以把它仅仅看作是你的程序的扩展。

VxD程序是Windows 9x特有的,它在Windows NT下不能运行。

所以如果你的程序是依靠VxD的,它就不能被移植到Windows NT平台上去。

VxD是系统中权力最大的实体。

由于它们可以对系统作任何事情,所以它们是极度危险的。

一个恶意的/错误的VxD程序可以毁掉整个系统。

对于恶意的/错误的VxD程序没有任何的保护措施。

驱动程序:英文名为“Device Driver”,全称为“设备驱动程序”是一种可以使计算机和设备通信的特殊程序,可以说相当于硬件的接口,操作系统只有通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。

因此,驱动程序被誉为“ 硬件的灵魂”、“硬件的主宰”、和“硬件和系统之间的桥梁”等。

刚安装好的系统操作系统,很可能驱动程序安装得不完整。

硬件越新,这种可能性越大。

菜菜熊之前看到的“图标很大且颜色难看”就是没有安装好驱动的原因。

在软件测试中:在自底向上测试中,要编写称为测试驱动的模块调用正在测试的模块。

测试驱动模块以和将来真正模块同样的方式挂接,向处于测试的模块发送测试用例数据,接受返回结果,验证结果是否正确。

随着电子技术的飞速发展,电脑硬件的性能越来越强大。

驱动程序是直接工作在各种硬件设备上的软件,其“驱动”这个名称也十分形象的指明了它的功能。

正是通过驱动程序,各种硬件设备才能正常运行,达到既定的工作效果。

硬件如果缺少了驱动程序的“驱动”,那么本来性能非常强大的硬件就无法根据软件发出的指令进行工作,硬件就是空有一身本领都无从发挥,毫无用武之地。

这时候,电脑就正如古人所说的“万事俱备,只欠东风”,这“东风”的角色就落在了驱动程序身上。

如此看来,驱动程序在电脑使用上还真起着举足轻重的作用。

从理论上讲,所有的硬件设备都需要安装相应的驱动程序才能正常工作。

但像CPU、内存、主板、软驱、键盘、显示器等设备却并不需要安装驱动程序也可以正常工作,而显卡、声卡、网卡等却一定要安装驱动程序,否则便无法正常工作。

这是为什么呢?这主要是由于这些硬件对于一台个人电脑来说是必需的,所以早期的设计人员将这些硬件列为BIOS能直接支持的硬件。

换句话说,上述硬件安装后就可以被BIOS 和操作系统直接支持,不再需要安装驱动程序。

从这个角度来说,BIOS也是一种驱动程序。

但是对于其他的硬件,例如:网卡,声卡,显卡等等却必须要安装驱动程序,不然这些硬件就无法正常工作。

第一章绪论驱动程序实际上可以理解为是一系列控制硬件设备的函数。

在DOS系统中,一个驱动程序可能是一个连到应用程序.EXE中的一个模块或者是与应用程序分开的一个独立部分;在Widows系统中,封装驱动程序的方法是制作一个DLL或VxD。

在早期,由于我们一般涉及的与计算机相关的硬件设备都是标准设备,它们的驱动程序是由厂家或专门的程序开发人员提供并加以封装,用户只需了解与驱动程序相连的Windows应用程序接口(API),而无需知道其内部运行机制。

但是如果硬件是非标准设备,我们必须针对该特定硬件自己来设计Windows环境下的设备驱动程序。

the Application Programming Interface API我所面对的硬件是一块超声波探伤卡,它集成在一块PCI插卡上,桥接芯片采用了PCI2040,因为它可以和DSP无缝连接。

我要做的工作是首先利用主机通过并口启动模拟采样部分,当采样数据放大后进入A/D变换后存入储存器,在数据存储器中存满一帧时,硬件向主机发中断,主机响应中断后通过PCI2040芯片读出存放在数据存储器中的采样数据,然后进行后续处理并将结果显示于屏幕。

我编写的应用程序的软件平台是Window95/98,采样的工具是VisualC++6.0(简称VC++),因为它是一种面向对象的编程语言,具有良好的交换性,可以根据用户对界面上的控件或菜单操作作出相应的处理,而且它可以自动根据要求生成框架,我们要做的只是对空的函数框架进行填充。

由于应用程序运行在Ring3级,它不能对硬件进行直接访问,也不会响应硬件中断,必须通过驱动程序来响应中断以及访问硬件。

该硬件显然不是Windows标准组件,系统不会提供相应的VxD驱动程序,因此必须自己编写PCI2040的硬件安装信息文件和驱动程序。

值得一提的是在通过并口与硬件通信时理论上也得写VxD但是由于并口是Windows标准组件,Windows已经封装了一些常用的API函数(如_inp()和_outp()等函数),可以在应用程序中直接使用,而且像打印机等利用并口传输数据的硬件的驱动程序已经被认为不属于虚拟设备驱动程序了。

RING3在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃。

比如:清内存、设置时钟等。

如果所有的程序都能使用这些指令,那么你的系统一天死机n回就不足为奇了。

所以,CPU将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通的应用程序只能使用那些不会造成灾难的指令。

形象地说,特权指令就是那些儿童不宜的东东,而非特权指令则是老少皆宜。

Intel的CPU将特权级别分为4个级别:RING0,RING1,RING2,RING3。

Windows只使用RING0和RING3,RING0只给操作系统用,RING3谁都能用。

如果普通应用程序企图执行RING0指令,则Windows会显示“非法指令”错误信息。

因为有CPU的特权级别作保护。

在本论文安排上首先介绍驱动程序的产生背景、实现原理和开发工具,然后介绍PCI 总线及PCI2040芯片,最后说明我的驱动程序以及相应的应用程序。

第二章Windows环境下的驱动程序在DOS操作系统时代,对于一个应用程序而言它总认为自己是唯一运行的程序,因此常常可以直接访问硬件,独占所有的系统内存以及系统运行时间,当然也就不需要设备驱动程序。

但是到了Windows时代,DOS应用程序并不是唯一运行的程序,系统中同时可能有若干个应用程序在运行,这就使得系统不可能让它随意的直接访问硬件,否则就会引起混乱导致系统崩溃。

为了解决这个问题,人们提出了将系统的资源虚拟化,让应用程序运行在一个虚拟的环境中的虚拟机(VM)上,而管理程序和驱动程序运行在实际机器上(Ring0级),由它们来处理针对硬件的操作。

2.1虚拟机(VM)虚拟资源是由系统产生的假象,它是硬件(甚至是软件)资源的仿真,当系统虚拟了所有或者几乎所有的程序可以访问的资源时,它就创造了一个“虚拟机”(VM)。

概括起来,Windows的虚拟机完全透明地仿真了以下地资源和性能:●可访问的内存空间;●I/O操作;●中断操作;●外围设备(显示器、键盘等);虚拟机的管理主要由虚拟机管理器(VMM)完成。

VMM利用系统的硬件创造了几个相互独立的虚拟机,每个虚拟机都有自己的虚拟环境,而且每个虚拟环境可能与物理环境根本不同。

让所有的Windows应用程序(Win16应用程序和Win32应用程序)运行在一个VM上,称为系统VM;而每一个DOS应用程序都分别运行在各自的一个VM上,这样便解决了D OS和Windows应用程序的兼容问题。

2.2处理器运行模式及各种程序优先级为了创建和维护虚拟机,VMM开发了80386以及以后的兼容处理器的特殊性能。

这些处理器有三种运行模式:实模式、保护模式和V86模式,它们决定了处理器所能寻址的地址空间,如何实现逻辑地址到物理地址的转换以及如何保护对内存和I/O端口的访问。

Win dows95/98利用了其中的保护模式和V86模式两种模式,以下各项也是针对这两种模式而言。

Windows95/98执行环境支持四种不同的基本模式:管理程序、Win32应用程序、Win 16应用程序和DOS应用程序。

其中管理程序在Ring0级(最高级)中运行,能够访问和控制实际硬件环境,也就是说它们在真正的计算机上运行,而不是在虚拟机上运行,在所有构成Windows的组件中,只有VMM和VxD在管理环境中执行。

Windows应用程序在Ring3级(最低级)的保护模式上运行,它们不能直接访问硬件,一旦执行一个对硬件的操作就会引起一个异常事件,这时处理器切换到Ring0级,并且将控制权交给相应的控制器。

所有Windows应用程序分享一个系统虚拟机。

每个DOS应用程序运行在各自的V86虚拟机(类似于系统虚拟机)上,标注为Ring3级(最低级),它访问的硬件资源和中断也被隐藏和虚拟了。

2.3如何实现虚拟机当在虚拟机中执行程序时,Windows必须能够捕获并透明的“代替”以下功能:●对I/O端口查询●对一个内存映射的外围设备查询。

●可能导致传送到虚拟机之外的操作,如一个异常时间或中断。

2.3.1捕获I/O操作不论保护模式还是V86模式,操作系统都可以捕获输入和输出指令来防止应用程序直接访问I/O映射的设备。

Windows98/95使用I/O优先级(IOPL)和I/O允许映射(IOPM)(‘0’表示拒绝,‘1’表示允许)来控制VM访问I/O地址。

在保护模式中,每个代码段都有一个相关的优先级描述器,它存储在描述器列表中。

当在保护模式中执行一个I/O指令时,处理器将段的IOPL和当前代码段的优先级(CPL)比较,如果CPL IOPL且IOPM=0,处理器才执行指令,否则产生一个异常事件。

在V86模式中,处理器只参照IOPM,与IOPL无关。

Windows和它的标准组件VxD可以捕获PC机上的所有标准I/O设备,由于我们使用的不是标准硬件,因此要自己编写VxD,流程也相似先向VMM申请捕获我们的硬件端口的服务,安装回调处理器,当VM访问该端口时产生异常进入我们的回调处理中,由我们自己编写的函数进行处理。

相关文档
最新文档