美国微软公司出品的windows98以其友好的图形用户界面,在我国赢得了广泛的市场。在给广大办公环境工作人员带来方便的同时,也给不少工程技术人员带来了一些麻烦。一些原本在dos下很容易编出的控制硬件的程序,现在在windows98下就不那么容易实现了。作为一个完善的操作系统也必须能控制硬件,象dos那样直接与硬件打交道是windows98不提倡的。它需要开发专门的硬件设备驱动程序,即通过一系列的虚拟设备驱动程序来管理硬件,如:进行中断响应、i/o端口读写或直接存储器存取(dma)。windows98内核管理机制非常复杂,因而编写虚拟驱动程序也变得十分困难,要想编写虚拟驱动程序,就必须对windows98的内核有所了解。
1 windows98的内核管理机制
在windows95三年后推出的windows98虽然扩充了许多新的设备驱动特性,如对agp、usb、dvd的支持,但在内核上却和windows95基本一样,它们都是基于dos内核的操作系统。windows98系统核心(kernel)由虚拟机管理器(vmm)和vxd(virtual device driver)的集合组成。kernel提供了900多个服务函数来管理内存、控制物理设备、处理中断、创建网络协议栈、管理文件系统等,这些服务函数都可以被自己写的vxd调用。虚拟机(vm)是一个可运行的任务,包含应用程序、支撑软件、内存和cpu寄存器。在windows98下有系统虚拟机和dos虚拟机两种。虚拟机管理器(vmm)是在系统级核心运行的32位保护模式操作系统,它运行于ring0,而且不可重入。vmm主要功能是创建、运行、监控和终止虚拟机。vxd即虚拟设备驱动程序,是用来扩展windows操作系统功能的一类程序。由于vxd运行在系统的ring0级,拥有与操作系统同等的级别,所以我们可利用它来支持硬件设备的管理。虚拟可编程中断控制器(vpicd)是负责管理所有硬件中断事件的程序,它本身也是一种vxd,能提供缺省的中断处理函数或者允许其它vxd重载中断处理函数。
2 windows98下应用程序权限级别
intel的80x86cpu系列芯片可在三种模式下工作:实模式、保护模式和v86模式。实模式是ms-dos的运行环境。windows98只利用了两种模式:保护模式和v86模式。保护模式给我们带来很多优越性,如应用程序不再受1m内存的限制,理论上,在保护模式下,cpu可以进行4096m内存的寻址。但在保护模式下,所有的应用程序都有权限级别(privilege level)。权限级别按优先次序分为四等:0、1、2、3。0级是最高级别,操作系统就运行在0级,运行在ring0级的应用程序可以执行所有的指令并可直接对硬件、中断和文件系统进行物理访问。如果应用程序拥有的权限级别是第3级,那么它能执行的指令是有限的,对硬件的很多直接操作是不能实现的。在windows中,一般的应用程序是运行在ring3级的(如用visual c++、borland c++、visual basic、delphi、c++ builder等sdk工具开发出的应用程序)。它们享有的权限是最低的,受到了保护模式的摫;它们没有权限去绕过操作系统直接对硬件操作。
有了权限级别,操作系统就有机会在中断和i/o操作上产生撔槟铍效果。由于操作系统的权限为0级,它就可以捕获权限不为0级的应用程序的中断和i/o请求,然后建立缓冲队列,再一一进行串行处理。为了使自己的应用程序也能直接处理硬件,就需要编写专门的vxd。由于vxd是作为操作系统的组件运行于第0级,因而可以利用它来捕获特定的硬件操作,完成我们需要的任务。
3 windows98下虚拟设备驱动程序的开发工具和基本编程方法
微软为驱动程序的开发提供了设备驱动程序工具箱(ddk),基于汇编语言的编程方式和许多vmm服务都使用寄存器的调用方式,确实非常难学,没有深厚的汇编语言和硬件基础很难在短时间里开发出自己的vxd。
程序员可利用c或c++语言编写自己的vxd,而不必操心许多繁琐的细节。它的基本编程方法是:用vtoolsd自带的quick vxd程序快速生成程序框架,在vc++或borland c++中打开此框架的工程文件,并写进特定的处理代码,编译后就可得到所需的vxd文件。
4 一个中断程序实例
用vtoolsd 2.03、vc++5.0为自制的pc/xt总线扩展卡开发了虚拟设备驱动程序audcard.vxd。该卡每20ms申请一次中断,中断由应用程序动态载入系统的audcard.vxd响应并加以处理。中断服务程序isr(interruptservice routine)结束后,调用函数shell_postmessage()向应用程序窗口发送自定义消息。应用程序接受消息后,再通过函数deviceiocontrol()与vxd的接口函数onw32deviceiocontrol( )互传缓冲区数据。程序结束即可动态卸载vxd。
当中断发生时,处理器转换为ring0级保护模式。windows系统并不像dos那样通过中断描述符表idt(interruptdescriptortable)直接指向中断处理过程,而是由idt入口指向vmm中的程序。该程序将判断是否为中断调用,如果是,则把中断控制权交给虚拟可编程中断控制器vpicd(virtualprogrammable interrupt controllerdevice),vpicd实际上是一个重要的vxd。vpicd再将其交给另一个注册了该中断的vxd(如audcard.vxd)来处理。vxd程序是通过调用vpicd服务vpicd_virtualize_irq来注册中断的。
虚拟设备驱动程序audcard.vxd的部分源代码audcard.h和audcard.cpp在网上,此应用程序使用了下列函数:createfile()动态加载vxd、closehandle()并动态卸载vxd、pretranslatemessage()截获消息、deviceiocontrol()与vxd互传缓冲区数据。虚拟设备驱动程序audcard.vxd经调试后工作正常,未发生过任何丢失数据或死机的现象。
下面是虚拟设备驱动程序audcard.vxd的部分源代码audcard.h和audcard.cpp,限于篇幅,由quickvxd自动生成的audcard.mak未列出。
①audcard.h
//audcard.h - include file for vxd audcard
#include
#define device_class audcarddevice
#define
audcard_deviceid undefined_device_id
#define audcard_init_order
undefined_init_order#define audcard_major
#define audcard_minor 0
#define my_irq 5 //定义5号中断
class myhwint:public vhardwareint
{
public:
myhwint():vhardwareint(my_irq,0,0,0){}
virtual void onhardwareint(vmhandle);
};
class audcarddevice :
public vdevice
{
public:
virtual bool
onsysdynamicdeviceinit();
virtual bool onsysdynamicdeviceexit();
virtual dword onw32deviceiocontrol(pioctlparams pdiocparams);
myhwint* pmyirq;
};
class audcardvm : public
vvirtualmachine
{
public:
audcardvm(vmhandle hvm);
};
class audcardthread : public vthread
{
public:
audcardthread(threadhandle hthread);
};
②audcard.cpp
//audcard.cpp - main module for vxd audcard
#define device_main
#include audcard.h
declare_virtual_device(audcard)
#define wm_user_postvxd
0x1000
//自定义消息
#undef device_main
audcardvm::audcardvm(vmhandle hvm) : vvirtualmachine(hvm) {}
audcardthread::audcardthread(threadhandle hthread) :
vthread(hthread) {}
bool audcarddevice::onsysdynamicdeviceinit()
//动态加载时初始化
{
……//硬件初始化
pmyirq=new myhwint();
if(pmyirq&&pmyirq->hook()) //挂接中断
{
pmyirq->physicalunmask(); //允许中断
return true;
}
else return false;
}
bool
audcarddevice::onsysdynamicdeviceexit()
//动态卸载过程
{
delete pmyirq;
return true;
}
dword
audcarddevice::onw32deviceiocontrol(pioctlparams pdiocparams)
//与win32应用程序的接口函数
{
……
}
void
myhwint::onhardwareint(vmhandle hvm)
{
…… // 中断处理
shell_postmessage(appwnd,wm_user_postvxd ,0,0,0,null);
//向应用程序窗口发送消息
sendphysicaleoi(); //通知vpicd中断结束
}
用vtoolsd 2.03、vc++ 5.0为自制的pc/xt总线扩展卡开发了虚拟设备驱动程序audcard.vxd。该卡每20ms申请一次中断,中断由应用程序动态载入系统的audcard.vxd响应并加以处理。中断服务程序isr(interrupt service routine)结束后,调用函数shell_postmessage( )向应用程序窗口发送自定义消息。应用程序接受消息后,再通过函数deviceiocontrol( )与vxd的接口函数onw32deviceiocontrol( )互传缓冲区数据。程序结束即可动态卸载vxd。
这样一个中断实例就完成了。
以上实例我们已在vtoolsd3.01和vc++6中调试通过,并已成功地在我们开发的小型实时光谱能量辐射仪中得到应用。
vxd作为现在流行的编程技术已逐渐受到广泛的关注,在工程技术中必将有着广阔的应用前景。学习、使用此技术将在科学研究中给我们带来便利。
超导磁共振成像设备以进口贸易为主,2020年德国是主要进口市场
Visual Studio 2019 +STM32实现串口通讯
全面碾压三星,台积电5nm斩获大批客户
微型电流模式升压DC/DC变换器
贵出天际!几款你很难买到的手机:小米MIX、华为荣耀Magic、魅族Pro6 Plus、华为Mate9保时捷版
Windows下硬件中断虚拟设备驱动程序开发工具和编程方法
中国移动3G上网危险扩张 投诉集中爆发
中交宇科与星云互联的合作迈入新时代
新时代下的智慧医疗该怎样落地
AI和5G经历振荡期 芯片企业如何应对
锂离子电池产量71.5亿只,同比增长1.3%
高通微软又有新合作?
中兴就是一杆秤,所有的企业应以它为准星
节能减排,加强污水垃圾处理和污染治理!
50条电气控制知识和电气实用速算法资料合集
程序员怎样高效的学习
电流探头在家电性能测试中的应用
苹果或在今年10月份发布16英寸版MacBookPro 整机价格预计约合人民币2.2万元
基于DSP芯片tms320lf2810实现永磁同步电动机反推控制的应用方案
中国电信“建设网络强国 引领智能未来”亮相PT展带来五大看点