实现Windows环境下对硬件中断的控制方法

在计算机控制领域,随着硬件的发展,一些原本十分复杂的控制算法的设计和仿真变得越来越容易实现。与基于vme、multibus以及std总线的平台相比,基于isa总线的高性能pc工控机(ipc)无疑是近来应用最为广泛的主流产品。这主要得益于ipc与pc的软件兼容性,此外其开放性结构、外围高性能i/o模板的不断涌现以及实进工业网络的迅速发展都为ipc创造了有利的发展环境。可以说,ipc的时代已经到来。此外,在当今的计算机控制领域中,控制软件是否基于windows平台已经成为产品是否有竞争力的重要标准之一。目前基于windows平台的相关产品已经占据了市场份额的90%。而windows 9x和windows nt凭借其出色的多任务、图形用户接口(gui)、性能优越的硬件兼容性以及卓越的32位软件环境等性能已经越来越广泛地被应用于工业控制,成为实现实时控制的优秀平台。在windows9x(95、97、98)下,用户如果需要实现对硬件的中断、dma或存储空间物理地址等资源进行访问,必须通过设备驱动程序来进行硬件操作;在windowsnt下,即使是简单的i/o操作,也需要编写驱动程序方能与硬件打交道。
兼容x86指令的微机cpu运行时有4个优先级,ring0~ring3。操作系统与驱动程序运行在ring0级,ring3级,对资源控制受到一些限制。对于ring0级的驱动程序而言,它的编写和调试要求程序开发者掌握windows9x、nt及windows2000的内核管理机制,对于开发人员来讲这有相当大的难度。在这里,使用美国jungo公司出品的windriver工具包,在不更改程序代码的前提下,完成了在多个操作系统下对硬件中断的一致处理,很方便地解决了硬件与程序在不同系统下的移植问题。
1 windows下硬件中断的管理机制
在多任务的环境里,硬件设备中断管理程序是非常重要的系统级程序。它不仅要把硬件发生的中断时间传给相应的驱动程序,还要允许某些设备驱动程序处理它们特殊的中断服务。在windows平台下,vpicd(虚拟可编程中断控制器)就是这样的硬件设备管理程序,它负责管理所有的硬件中断时间。pc机的硬件中断需要确定硬件中断的irqs(中断申请号),对一个特定的irq中断源,vpicd或提供缺省的中断处理函数,或允许其它vxd重载中处理函数。
vpicd提供的缺省中断处理是:首先置中断禁止,再触发相应vm中的中断处理函数。因为vpicd实现了对ppic的虚拟化,所以当vm中的中断处理函数发送eoi(中断处理结束指令)时,vpicd即对ppic发eoi指令。最后,vpicd控制处理函数的返回操作,恢复中断,并置vm状态为vm进入中断前的状态。当vpicd对某些中断的缺省处理不够充分或则不太合适时,就需要亲手编写一个vxd,在其中实现中断的虚拟化。vxd将决定如何处理硬件中断以及如何调用vm中的中断处理函数。
2 windriver工具包简介
windriver是美国jungo公司出品的用于编写驱动程序的一种工具包,主要针对isa/pci插卡,4.2版本以后还提供了usb的开发工具。最新版本4.40版所编写的程序兼容性十分强大,包括了windows9x、windows nt、windows2000、solaris(intel)、vxworks(intel)、os/2等诸多操作平台。windriver主要包括一个windriverwizard、一个windriver发行包、多个公用程序以及大量的例程。
(1)windriverwizard
这是一个友好的windows向导界面。运行windriverwizard,然后,选择“generatecode”选项,windriverwizard会为你的插卡产生基本的程序代码。4.2版本以后还提供了多种编程语言选择,几乎包括了所有流行的编程语言,如vc4~vc6、borland c++builder3~4、pascal、delphi、linuxmake、solariesmake等等。这就让用户不必去学新的编程语言,很容易地直接上手。
(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、amcc5933、v3、altera、gt64等等,提供了特定的检测程序和相应的api函数,大大减轻了用户的编程难度。
3 windriver的驱动程序编程模式原理
windriver编程有两种模式。一种模式是用户模式,这种模式实际上不是让用户来编驱动程序,而是利用软件自身提供的驱动程序windrvr.vxd和windrvr.sys,用户所面对的中是驱动程序给出的相应功能接口;即使是这个接口,也用高级语言进行了很好的封装,使用十分容易。另一种模式是“核心插入”模式用kernelplugin方式进行编程,形成。vxd和。sys文件,。当用户有特殊的速度要求时,后者是较好的方式。
对于对操作系统内核了解不多的开发者,使用用户模式,这里要特别注意以下几个功能函数:
(1)wd-open()--获得驱动程序(指windrvr.vxd或windrvr.sys)的句柄,它实际上是调用了create-file()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下也能够稳定运行。对于windows9x系统,注意将windrvr.vxd拷贝到c:\windows\system\vmm32目录下;对于windowsnt系统,注意将windrvr.sys拷贝到c:\winnt\system32\drivers目录下。listen_interupt.c程序框架如下,该程序实现了中断12的截获:
listem_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来传递从interruptthreaenable()得来的信息
void interrupt_handler(pvoid pdata)
{
//在这里加入你要做的中断处理代码
prinft('截获中断的数目为%d\n',intrp.dwcounter);
}
//主函数
int main()
{
wd_card_refister cardreg;//建立插卡登记项目的一个实例
wd_version vervuf;
hwd=wd_open();//获得驱动程序的句柄
if(hwd==invalid_handle_value)
{
printf(打开windrvr出现错误!\n);
return0;
}
bzero(verbuf);
wd_version(hwd,&verbuf);
if(verbuf,dwver
{
printf(windrvr版本不正确,这里需要的版本为:%d\n,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,dwintrrupt=my_irq;
cardreg.card.item[0].i.int.dwoptions=1;
cardreg.fghecklockonly=true;
wd_cardreguster(hwd,&cardreg);
if(cardreg.hcard==0)
{
prinft('无法锁定设备!');
}
else
{
handle thread_handle;
bzero(intrp);
intrp.hinterrupt=cardreg.card.item[0].i.int.hinterrupt;
intrp.cmd=null;
intrp.dwcmds=0;
intrp.dwoptions=0;
printh('开始中断线程\');
//这里调用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环境下对硬件中断的直接控制,很方便地在不同系统下进行移植。

统计分析:锂电池三种不同封装方式
大基金二期及鑫益合升向长鑫新桥增资390亿元!
Intersil推出90%效率背光LED驱动器 延长平板电脑与移动设备续航时间
USB充电器的过去与现在之Type-C达到能源效率标准
各国政府的支持将进一步推动智能电缆保护系统预测期内市场的增长
实现Windows环境下对硬件中断的控制方法
通过利用单片机实现RLC、频率及相位差测量仪的应用方案
正版SOLIDWORKS 2023新功能之快速看到仿真结果
突发!全球PCB供应链巨头厂房大火
全球数字资产币币交易系统开发公司|深圳数字资产抵押借贷平台APP开发
赛灵思发布史上最大容量FPGA芯片VU19P
一文分析2020年全球及中国市场的外部存储
谷歌提醒用户从Chromium Edge切换到Chrome浏览器
西门子S7-200PLC编程的一些小技巧
IAM即热饮水机:16档温控+智能夜灯,助妈妈轻松喂夜奶
无人驾驶中的“激进”与“保守”之争
意法半导体:在中国机顶盒芯片市场占30%以上份额
串联谐振装置有哪几个部件?都有什么作用?
同步电机的分类
盛科网络成伟:混合云是未来的重点发展方向