Windows9X硬件中断设备驱动程序的开发(2)
2008-04-09 04:08:55来源:互联网 阅读 ()
VOID WriteCMOS(BYTE reg,BYTE value);
BYTE ReadCMOS(BYTE reg);
class IrqtestDevice:public VDevice{
prblic;
virtual BOOL OnSysDynamicDeviceInit();
virtual BOOL OnSysDynamicDeviceExit();
virtual DWORD OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams);};
class IrqtestVM:public VVirtualMachine{
public;
IrqtestVM(VMHANDLE hVM);};
class IrqtestThread:public VThread{
public:
IrqtestThread(THREADHANDLE hThread);};
//IRQTEST.cpp-main module for VxD IRQTEST
#define DEVICE-MAIN
#include"irqtest.h"
#undefDEVICE-MAIn
Declare-Virtual-Device(IRQTEST)
VPICD-HWInt-THUNK RTCInt-Thunk;handler//中断Thunk
EVENTHANDLE hEvent;//Handle of timer event
IRQHANDLE RTCIRQHandle;//Handle for virtual IRQ
BYTE SavedStatusRegisterA;
BYTE SavedStatusRegisterB;//保存RTC设置寄存器
DWORD TickCounter;//中断计数器
DWORD*PostMsghWnd;//Ring3层应用程序的hWnd
HANDLE hWnd;
IrqtestVM::IrqtestVM(VMHANDLE hVM)
VVirtualMachine(hVM){}
IrqtestThread::IrqtestThread(THREADHANDLE hThread)
VThread(hThread){}
BOOL IrqtestDevice::OnSyaDynamicDeviceInit(){
VMHANDLE hVM;
hVM=Get-Cur-VM-Handle();
BYTE statreg;
DWORD status;
DWORD RTClockFreqIndex;
//挂接硬件中断需要调用虚拟可编程中断控制器(VPICD)来通知Windows此VxD负责处理此IRQ。在这里我们只用到了VPICD提供的五个不同的与IRQ相关的通知事件之一,即实际的硬件中断事件。
struct VPICD-IRQ-Descriptor IRQdesc;//此结构将被传入VPICD-Virtualize-IRQ例程进行初始化,以下是参数设置。IRQdese.VID-IRQ-Number=RTC-IRQ;//将要被虚拟的IRQ IRQdesc.VID-Options=0;//保留
//为了在此结构中设置中断服务例程的地址,我们将服务例程thunk的地址传递给VPICD-Thunk-HWInt,它将负带将thunk初始化并返回它的地址
IRQdesc.VID-Hw-Int-Proc=(DWORD)VPICD-Thunk-HWInt
(RTCInt-Handler,&RTCInt-Thunk);
IRQdesc.VID-IRET-Time-Out=500;
//此结构的其它变量在这里没有用到。
//通过VPICD-Virtualize-IRQ服务将已定义结构传入VPICD,VPICD分配IRQ并返回其句柄
RTCIRQHandle=VPICD-Virtualize-IRQ(&IRQdesc);
if(RTCIRQHandle==0)returnFALSE;//虚拟化失败
//保存初始RTC状态寄存器以便退出时恢复现场
SavedStatusRegisterA=ReadCMOS(STATREG-A);
SavedStatusRegisterB=ReadCMOS(STATREG-B);
RTClockFreqIndex=6;设置中断频率,见下文说明;
statreg=(SavedStatusRegisterA & ~0xF)|(RTClockFreqIndex & 0xF);
WriteCMOS(STATREG-A,statreg);
//设置RTC状态寄存器使得status register flags to enable it to assert its IRQ
statreg=ReadCMOS(STATREG-B);
statreg|=ENABLE-INTERRUPT;
WriteCMOS(STATREG-B,statreg);
ReadCMOS(STATREG-C);
TickCounter=0;//初始化中断计数器
//保证IRQ在PIC中未被屏蔽
VPICD-Physically-Unmask(RTCIRQHandle);
return TRUE;
}
BOOL IrqtestDevice:OnSysDynamicDeviceFxit(){
//恢复现场;
Cancel-Global-Event(hEvent);
WriteCMOS(STATREG-A,SavedStatusRegister A);
WriteCMOS(STATREG-B,SavedStatusRegister B);
VPICD-Physically-Mask(RTCIRQHandle);
VPICD-Force-Default-Behavior(RTCIRQHandle);
return TRUE;
}
DWORD IrqtestDevice::OnW32DeviceIoControl
(PIOCTLPARAMS pDIOCParams)
{
switch(pDIOCParams->dioc-IOCtICode){
case DIOC-OPEN;//CreateFile
{hWnd =0;//Ring 3层应用程序主窗口句柄初始化
return 0;}
case W32IF-PASS-EVENT:
PostMsghWnd=(DWORD*)pDIOCParams->dioc-InBuf;
hWnd=(HANDLE)*PostMsghWnd;//获得主窗口句柄
return 0;
default:return-1;}
return 0;}
BOOL -stdcall RTCInt-Handler(VMHANDLE hVM,IRQHANDLE hIRQ){
//在中断服务例程中,对中断计数器计数并向Ring 3层应用程序发送自定义消息;
if(hWnd&&(TickCounter0==0)){
SHELL-PostMessage(hWnd,WM-My-MESSAGE,0,0,NULL,NULL);}
TickCounter ;
ReadCMOS(STATREG-C);//清除RTC状态标志
VPICD-Phys-EOI(hIRQ);//指定VPICD清除此中断
return TRUE;//thunk将清除进位
}
//篇幅所限,针对COMS端口操作的两个函数ReadCMOS(BYTE reg)和WriteCMOS(BYTE reg,BYTE value)的源程序略,请参考VtoolsD连机帮助中的CHIME例子。
2.Ring 3级主应用程序设计
将生成的VxD放入主应用程序的工作目录中,用CreateFile()函数动态加载VxD。
hDevice=CreateFile("\\\\.\\irqtest.vsd",0,0,0,OPEN-ALWAYS,FILE-FLAG-DELETE-ON-CLOSE,0);
需要挂接中断时,调用DeviceIoControl()将主程序窗口的句柄传递给正运行的VxD。
Main-CWnd=AfxGetMainWnd();
inBuf[0]=Main-CWnd->m-hWnd;
if(! DeviceIoControl(hDevice,W32IF-PASS-EVENT,inBut,sizeof(PVOID),RetInfo,sizeof
(RetInfo),&cbBytesRetumed,NULL))
AfxMessageBox("DeviceIoCtl Failed!"MB-OK);//与VxD通讯失败
然后在自定义消息处理函数中加入自己的实时处理代码。需要说明以下几点:
在VxD的中断处理函数中可以加入对实时性要求最高的代码,原则上应尽快返回以提高中断频率和避免重入;
中断频率的选择参数n有以下选择:
n 频率(Hz) n 频率(Hz)
1 256 7 512
2 128 10 64
3 8192 11 32
4 4096 12 16
5 2048 13 8
6 1024 14 4
本文介绍的方法同样适用于编写其他普通硬件中断VxD。
在中断频率较高的数据采集系统中。可以设置双缓冲区来实现实时中断与处理线程的同步。
五、结论
本文在对PC和Windows 9X和9X进行了细致的研究之后,分析了在其上构造实时系统的方法,并通过详细的应用示例给出了具体的说明。本文使用的方法具有通用性和易用性,在笔者设计的24自由度仿人型机器人控制系统中运行良好。本文介绍的方法对于开发Windows 9X实时控制系统具有实际的参考价值。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
