阅读:1459回复:10
在普通PC机上正常运行的VXD,在PC104上响应中断有间歇了?
最近使用PC104(有PCI插槽)开发板,自己开发了PCI数据采集卡及
相关的驱动(VXD)、应用程序。现在遇到了如下的问题:程序在普 通PC机(奔2,566MHz,win98)上可以并行运行,可是在PC104(奔 3,533MHz,win98)上却发现每当在VXD中回调应用程序中的写文件函 数(或者什么也不做,只是直接返回)时,VXD就有50-100ms的间 歇,其间不响应中断,似乎是回调函数返回了才开始响应中断,跟 DOS程序运行相似。这与WIN98的多线程特点有些不符。 故此向大侠们询问,PC104是否有其本身的某些特点?项目紧 急,盼及时给以指点,不胜感谢!!! 使用的开发环境是: 1、PC1O4 主板型号:SPT4-533。 2、驱动程序的软件编译环境: 系统:WIN98 编译软件:VC++6.0和VtoolsD 3.05 驱动程序类型:VXD 3、开发的PCI卡的工作流图: (1)外部电路给PCI卡一个中断信号. (2)PCI卡向PCI总线发中断请求。 (3)VXD响应中断,在中断服务程序中启动数据接收。 **(4)一组数据接收完成,VXD回调应用程序中的数据保存函数(到硬盘)。 **(5)设置好PCI卡,准备下一次数据传送。 4、部分相关程序如下: /////////////////////////////////////////////////////////// ////////////以下是应用程序部/////////////////////////////// DWORD WINAPI CallBackAPC(PVOID param) ///回调函数。/// { ..........; fwrite(mytempt8bit,myfifosize,1,fp); ///将数据写到文件中。 ..........; } void main() ///主函数/// {...........; DeviceIoControl(hDevice,SETCALLBACK,CallBackAPC,0,0,0,0,0); /////////////传送回调函数的入口给VXD。////////////////// ..........; cout<<\"press ctrl-C to exit......\"<<endl; while(TRUE) {SleepEx(INFINITE,TRUE);} ///////等待回调。//////// .........; } /////////////////以上是应用程序部分///////////////////////// //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// ////////////////以下是驱动(vxd)部分//////////////////////// DWORD MyDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams) { ..........; switch(pDIOCParams->dioc_IOCtlCode) {...............; case SETCALLBACK: CallBackApc=pDIOCParams->dioc_InBuf; TheThread=Get_Cur_Thread_Handle(); return 0; ...............; } ............; } ////////////系统分配的中断号:11/////////////////// BOOL MyInt::OnSharedHardwareInt(VMHANDLE hVM) {...........; VWIN32_QueueUserApc(CallBackApc,(DWORD)&x,TheThread); /////条件满足时回调应用程序中的写文件函数。//////// ...........; } /////////////////////以上是驱动部分/////////////////// ////////////////////////////////////////////////////// 各项指标及遇到的问题是: 1、中断源频率为:1次/400us, 2、每400次中断后回调一次写文件函数,所以从VXD中回调应用程序 的频率为:1次/160ms。 3、在普通PC机(奔2,566MHz,WIN98)上软硬件都通过了调试:每 次VXD回调应用程序中的写文件函数时,VXD能并行地及时响应每次中 断。 4、在PC104(奔3,533MHz,WIN98)上测试同样的软硬件,却发现每 次VXD回调应用程序中的写文件函数时,VXD不能并行地及时响应每次 中断,存在50-100ms的间歇,直到回调函数返回才开始响应中断。 5、如果将回调函数改为直接返回(即不做任何处理、运算操作), 结果仍然同上。 6、如果在VXD中不回调应用程序中的函数,只作中断处理,则在 PC104上也可以看到每次中断都能及时响应。 |
|
沙发#
发布于:2003-03-24 18:37
pc104怎么会有PCI槽,是pc104+吗?再说P2也没有566啊,你的PC104是PIII的吗?那太高级了。
|
|
板凳#
发布于:2003-03-25 02:31
你的结构就有问题,怎么可以在回调函数中写盘。在普通PC机(奔2,566MHz,win98)上可以运行是你的运气,因为disk cache帮了你,而不是“并行”。
|
|
地板#
发布于:2003-03-25 09:23
谢谢大侠们的指点,我用的是PC104+,有PCI总线的。小弟实在是对操作系统不熟。只在参考书上看到,VXD调用VWIN32_QueueUserApc()后并不立即执行,只将入口放在队列中等待,但却不知道是不是在中断返回之后执行?按你的说发,那一般写盘应该怎样操作?请指点一下,谢了先。
|
|
地下室#
发布于:2003-03-25 11:44
中断把数据存入缓冲,应用程序把数据移出、存盘。存入和移出两者异步。通过事件或标志联系。
|
|
5楼#
发布于:2003-03-25 15:49
其实我在VXD中做了两个缓冲区,乒乓式传送。回调函数根据传回来的参数确定对哪个缓冲区进行数据处理并转移到应用程序中的一个数组中,然后将该数组写盘。回调函数是在应用程序中的,为什么不能在回调函数中写盘呢?回调函数在不在主函数线程中呢?它和中断处理函数是怎样的时序关系?大侠能不能讲仔细一点,谢谢了。
|
|
6楼#
发布于:2003-03-26 01:37
回调函数的线程属于调用他的线程。中断线程应该越短越好,而写盘的时间很长,特别是从休眠到复苏时。
两个缓冲区,乒乓式传送不是很好。一般用LIST结构(类似FIFO) |
|
7楼#
发布于:2003-03-26 11:31
“回调函数的线程属于调用他的线程”,那我在中断处理中回调,则回调函数就属于中断线程了,但如果这样的话,为何要在应用程序中将主线程睡眠呢?回调时是否唤醒了主线程?
我现在碰到的问题还包括:就算我在回调函数中不写盘,也不进行数据处理,而仅仅是调用一下后什么也不做就直接返回(即只有return 0;语句),仍然存在中断在回调的时候被间歇的情况。还有一个现象,就是间歇时间随缓冲区的大小变化(缓冲区越大,连续两次回调的时间间隔就越大)无规律变化。实在弄不明白这是什么原因引起的,请大侠们多多指点。 “LIST结构(类似FIFO)”是否就是循环链表结构?其实我的缓冲区是这样做的:由于我在VXD中要进行DMA传送,所以划了一片物理地址连续的缓冲区(1M),每来一次中断就将1K数据DMA传送到缓冲区中,然后地址递增1K(相当于FIFO指针),准备下一次数据传送,当缓冲区中的数据达到500K时(相当于FIFO半满),就回调一次CallBackAPC(),将缓冲区中的前半部分的数据取走;当地址递增了1M时(相当于FIFO全满),就再回调一次CallBackAPC(),将缓冲区中的后半部分的数据取走,同时将地址指针转移到缓冲区的开头(相当于FIFO空)。如果将前半部分、后半部分看作两个缓冲区,则相当于乒乓方式了。不知大家的缓冲区是怎么做的?请教一下了。 |
|
8楼#
发布于:2003-03-27 02:35
“回调函数的线程属于调用他的线程”,那我在中断处理中回调,则回调函数就属于中断线程了?
对 但如果这样的话,为何要在应用程序中将主线程睡眠呢? 为了把多余的时间片还给系统。 回调时是否唤醒了主线程? 不。 我现在碰到的问题还包括:就算我在回调函数中不写盘,也不进行数据处理,而仅仅是调用一下后什么也不做就直接返回(即只有return 0;语句),仍然存在中断在回调的时候被间歇的情况。还有一个现象,就是间歇时间随缓冲区的大小变化(缓冲区越大,连续两次回调的时间间隔就越大)无规律变化。实在弄不明白这是什么原因引起的,请大侠们多多指点。 系统回调要做许多工作,包括内存的切换。(WINDOWS的内存有一部分在盘上,所以时间不好控制) “LIST结构(类似FIFO)”是否就是循环链表结构?其实我的缓冲区是这样做的:由于我在VXD中要进行DMA传送,所以划了一片物理地址连续的缓冲区(1M),每来一次中断就将1K数据DMA传送到缓冲区中,然后地址递增1K(相当于FIFO指针),准备下一次数据传送,当缓冲区中的数据达到500K时(相当于FIFO半满),就回调一次CallBackAPC(),将缓冲区中的前半部分的数据取走;当地址递增了1M时(相当于FIFO全满),就再回调一次CallBackAPC(),将缓冲区中的后半部分的数据取走,同时将地址指针转移到缓冲区的开头(相当于FIFO空)。如果将前半部分、后半部分看作两个缓冲区,则 相当于乒乓方式了。不知大家的缓冲区是怎么做的?请教一下了。 乒乓方式(相当于FIFO半满)中间有较大的等待时间,一般1/10就可以写盘,缓冲区要能保存1-2分钟的数据。 |
|
9楼#
发布于:2003-04-08 16:44
既然“回调函数的线程属于调用他的线程”,那么是否意味着如果我在中断处理函数中回调,则回调函数就属于中断处理函数的一部分了?
那如果我用多线程方式,在一个线程中专门对缓冲区的数据进行处理和写盘,则是否就可以解决这个中断间歇问题了?用WIN32事件方式可以么? 请问什么地方可以找到关于回调函数、多线程与系统资源分配方面的详细资料?谢谢了,呵呵。 |
|
10楼#
发布于:2003-04-09 11:40
既然“回调函数的线程属于调用他的线程”,那么是否意味着如果我在中断处理函数中回调,则回调函数就属于中断处理函数的一部分了? 回复已经发到你的信箱 |
|