发信人: tsingxiao()
整理人: wenbobo(2002-12-24 09:15:45), 站内信件
|
Windows 中断编程
一、前 言
Windows提供强大的功能以及友好的图形用
户界面(GUI),使得它不仅广泛的用作管理事务型
工作的支持平台,也被工业领域的工程人员所关注。
但Windows3.1并非基于优先级来调度任务,无法
立即响应外部事件中断,也就不能满足工业应用环
境中实时事件处理和实时控制应用的要求。因此,如
何在Windows环境中处理外部实时事件一直是技
术人员尤其是实时领域工程人员所关注的问题。目
前已有的方法大都采用内挂实时多任务内核的方
式,如windows的实时控制软件包FLX等,而
iRMX实时操作系统则把Windows3.1当作它的一
个任务来运行。对于大型的工程项目,开发人员可采
用购买实时软件然后集成方式。对中小项目,从投资
上考虑就不很经济。如何寻找一种简明的方法来处
理外部实时事件依然显得很必要。
本文首先阐述windows的消息机制及中断机
制,然后结合DPMI接口,给出一种保护模式下中
断程序的设计方法,以处理外部实时事件。经实际运
行结果表明,该方法具有简洁、实用、可靠的特点,并
同样可运行于Win95。
二、Windows的消息机制
Windows是一消息驱动式系统,见图l。 Windows
消息提供了应用程序与应用程序之间、应用程
序与Windows系统之间进行通讯的于段。应用程序
要实现的功能由消息来触发,并靠对消息的响应和
处理来完成。
Windows系统中有两种消息队列,一种是系统
消息队列,另一种是应用程序消息队列。计算机的所
有输入设备由 Windows监控,当一个事件发生时,
windows先将输入的消息放入系统消息队列中,然
后再将输入的消息拷贝到相应的应用程序队列中”
应用程序中的消息循环从它的消息队列中检索每一
个消息并发送给相应的窗口函数中。一个事件的发
生,到达处理它的窗口函数必须经历上述过程。值得
注意的是消息的非抢先性,即不论事件的急与缓,总
是按到达的先后排队(一些系统消息除外),这就使
得一些外部实时事件可能得不到及时的处理。
三、windows的保护模式及中断机制
1.Windows的保护模式
保护模式指的是线性地址由一个选择符间接生
成的,该选择符指向描述表中的某一项;而实模式中
则通过一个段/偏移量对来直接寻址。80386(486)
CPU提仪的保护模式能力包括一个64K的虚拟地
址空间和一个4G的段尺寸。Windows3.1实现时有
所差别,它支持标准模式和增强模式。标准模式针对
286机器,不周本文探讨范围。增强模式是对386以
上CPU而言,windows正是使用保护模式来打破
lM的屏障并且执行简单的内存保护。它使用选择
器、描述器和描述器表控制访问指定内存的位置和
段。描述器表包括全局描述器表局部描述器表、中
断描述器表。保护模式与实模式有许多不同。其中
显著的差异是访问内存的机制不同。
2.中断机制
(1)实模式中断
为了便于理解,我们先回顾实模式中断。
在实模式下,中断向量表IVT起到相当重要的
作用。无论来自外部硬件的中断或是内部的软中断
INTn,在CPU中都产生同样的响应。
①CPU将当前的指令指针寄存器(IP)、代码段
寄存器(CS)、标志寄存器压入堆栈。
②然后CPU使用 n值作为指向中断向量表
IVT的索引,在IVT中找出服务例程的远地址。
②CPU将此远地垃装入CS:IP寄存器中,并开
始执行服务例程。
④中断例程总以IRET指令结束。此指令使存
在堆栈中的三个值弹出并填入CS、IP和标志寄存
器,CPU继续执行原来的指令。
(2)保护模式中断
保护模式中断过程与实模式中断过程类似,但
它不再使用中断向量表IVT,而使用中断描述符表
(IDT)。值得一提的是,Windows运行时IVT还存
在,应用程序并不使用它,Windows仍然使用,但含
义已不同‘
(1)IVT结构:IVT在RAM的 0000:0000之
上,占据开始的1024字节。它仍然由 BIOS启动例
程设置,由DOS填充到RAM中。
②IDT中断描述符表:保护模式下,Windows
操作系统为实现中断机制而建立的一个特殊表,即
中断描述符表IDT。该表被用来保存中断服务例程
的线性地址,它们是真正的24位或32位地址,没有
段:偏移值结构。中断描述器表最多可含有256个例
程说明,详细说明请见[3]。 IDT结构见图2。
②当中断或异常发生时,处理过程与实模式类
丁当前的CS; IP值和标志寄存器值被存储。保存
的内容还包括CPU其他内部寄存器的值,以及目
前正在被执行的任务的有关信息(若必须发生任务
切换的话)。CPU设法获取中断向量后,以它为索引
值查找IDT中的服务例程远地址,接着将控制转
移到该处的服务例程。这是与实模式转移到IVT的
不同所在。保护模式使用IDTR寄存器分配和定位
内存中的IDT中断描述符表。IDT在内存中是可移
动的,与IVT固定在内存中刚好相反。 IDT中断描
述符表在 Windows中起决定性的作用。理解了
windows保护模式的中断机制。有助于我们理解
中断服务程序的设计,它的关键就在于如何将服务
例程的地址放入IDT中断描述符表中。当中断发生
时,如何将断点地址及CPU各寄存器值保护起来,
中断结束时,如何将保护的值恢复。 windows系统
本身并不提供实现上述功能的API,而DOS保护模
式接口DPMI正具备了上述的功能。
下面我们首先介绍DPMI接口,然后基于它实
现Windows下中断服务程序的设计。
四、DOS保护模式接口 DMPI
Windows除了标准服务外,还支持一组特殊的
DOS服务,称为DOS保护模式接口 DPMI,由一些
INT2FH和INT31H服务组成。它使应用程序能
够访问 PC系列计算机的扩充内存,同时维护系统
的保护功能。 DPMI通过软件中断31h来定义了一
个新的接口,使得保护模式的应用程序能够用它作
分配内存,修改描述符以及调用实模式软件等工作。
Windows为应用程序提供 DPMI服务。即
Windows是DPMI的宿主(host),应用程序是DP
MI的客户(client),可通过INT31H调用得到DPMI服务。
INT 31H本身提供多功能。其中它的中断
管理服务允许保护模式用于拦截实模式中断,并且
挂住处理器异常。有些服务能够和 DPMI宿主合
作,以维护应用程序的虚拟中断标志。
可以用INT31H来挂住保护模式中断向量,以
中断方式处理外部实时事件。利用 INT 21H,功能
0205H:设置保护模式中断向量,将特定中断的保护
模式处理程序的地址置入中断向量里。调用方式:
AX=0205H,BL=中断号,CX:(E)DX=中断处理
程序选择符:偏移值。返回:执行成功CF=清零,执
行失败CF,置位。
挂住/解挂中断向量的时机很重要。主窗口第一
次被创建时会传送它WM—CREATE消息,这时是
挂住中断向量的最好时机。退出时需解挂向量,否则
Windows可能崩溃。上窗口接收到WM_DESTROY之后进行
解挂工作,是最适合的。解挂向量
可先用INT35H,0204H功能将老的中断向量保存,
退出时用INT35H,0205H恢复。
五、编程实现
有了DPMI的支持,我们就可以很方便地处理
数据采集、串行通信等工业过程中的实时事件。下面
以Windows3.1平台下中断方式实现的串行通信为
例,说明中断程序的编制和实现。为便于参考,给出
了详细的代码。开发平台BC3.1/BC4.5,其本身支
持0.9版的DPMI,无需运行其它支持DPMI的软
件。编程语言C,可与C++混合编译。
初始化COM1,9600波特率,每字符8bits,1个
停止位,中断接收,查询发送。
//windows asy COmmunica60n
//by Li Xiumi98
//last modified on June25,1996
#include<windows.h>
#include<dos.h>
void interrupt far DataReceive() ;
void interrupt far( * old_vector)();
unsigned char dataCom_r[1024],datacom_s[1024]:
int inflag=0 ;
unsigned int s8259;
int InitCom1()
{
s8259=inportb(0x21);
outportb(0x21,s8259&0xe8);
outportb(0x3fb,0x83);
outportb(0x3f8,0x0c);
outportb(0x3f9,0x00);
outportb(0x3fb,0x03);
outportb(0x3fc,0x08);
outportb(0x3f9,0x01);
return 1;
}
void interrupt far DataReceive()
{
static int i=0 ;
char rechar =0 ;
rechar=inportb(0x3f8);
if(inflag==0)
{
if(rechar!='s'&&i==0)
{
i=0;
goto l1;
}
datacom_r[i++]=rechar;
if(rechar=='e')
{
inflag=1;
i=0;
}
}
l1:outportb(0x20,0x20);
}
void InitCom(void)
{
asm{
cli;
mov ax,204h
mov bl,0ch
int 31h
sti
}
old_vector=MK_FP(_CX,_DX);
asm{
cli
mov ax,205h
mov bl,0ch
mov cx,seg datareceive
mov dx,offset datareceive
int 31h
sti
}
InitCom();
}
void restore_Comm(void)
{
outportb(0x21,s8259);
asm{
cli
mov ax,205h
mov bl,0ch
mov cx,seg old_vector
mov dx,offset old_vector
int 31h
sti
}
}
在窗口第一次被创建时会传送它WM_CREATE消息,
这时调用initCom()即可。在主窗口关
闭时,即主窗口中收到 WM_DESTROY消息时,调
用Restore Comm()恢复原来的状态。
这样在对串口初始化,设置中断服务例程后,通
信事件发生时,会立即跳入中断子程序中执行,越过
系统的消息队列,达到实时处理通信事件的目的。而
数据处理模块可通过全局标志f1,8访问全局的数
据通信缓冲区获取实时数据。这种实现方式与基于
消息机制的Windows通信API实现相比具有实时性强的的特点,
因为它超过了Windows 系统的两极消息机制,上述
程序已在实际系统中得到应用。在windows3.1支持下同时运行
三个Windows任务,服务器SERVER(内有实时串行通信,
多个网络数据子服务,),客户CLIENT,FOXPRO数据库系统
。整个系统运行良好。切换到WIN95平台下,系统也运行良好 。
-- 我
既不能达而兼善天下
只好穷而独善自身
青山处处 斯民如土矣……
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.253.41]
|
|