阅读:3110回复:8
如何实现数据的实时采集?
各位大虾好!
小弟我在用 98ddk 开发 wdm 驱动程序,碰到一个问题,特向大虾求救。 小弟的驱动程序是要实现视频的实时采集,要求将每一次中断发来的数据及时传递给上层程序。我是通过不停的往驱动程序发ReadFile请求来实现的,而且是缓冲I/O方式,效率很低下。我想知道是否可以使用直接I/O方式,怎么实现?还有,我觉得,即使可以使用直接I/O方式,也只是效率提高的问题,并不能保证数据的实时采集。那么,如果要实现数据的实时采集,应该通过什么方式进行。事件通知可以吗?或者,可不可以使用回调的方式(也就是在驱动程序中可不可以锁定应用程序地址空间)? |
|
最新喜欢:hapi |
沙发#
发布于:2001-06-18 11:08
驱动程序通知WIN32的方法,我们一直在探索,但没有成功.
我们与你有同样的问题. 如果你做到了,请共享一下谢谢. |
|
板凳#
发布于:2001-06-19 11:07
你好:
我个人认为,一方面有技术上的挑战,一方面是不是可以想想应用的可能性问题,比如:“实时”的要求,W32程序一定要直接取WDM传回的数据吗? |
|
地板#
发布于:2001-06-19 11:58
WINDOWS本身是多任务的操作系统,如果实时性要求非常高,肯定是很难胜任,我们以前做的加密卡是处理38M视频,是在卡上用硬件做的,驱动程序只是传递一些控制信息到卡上。
不知道你要处理的视频流实时性要求有多高,如果是数字卫星电视接收卡之类是分分钟钟没问题。 你完全可以用直接IO,具体实现也很简单呀,我很少用缓冲IO的。即使数据量不大我也用直接IO。 用事件通知是一个比较可行的办法。 至于回调的方式我看很困难。 |
|
|
地下室#
发布于:2001-06-19 16:21
我也作视频的实时采集,在WDM类程序中同样碰到了问题:不知道怎样得到一个虚拟地址的物理地址,应该类似于shilo所说的“在驱动程序中可不可以锁定应用程序地址空间“,因为我们的硬件有DMA功能,现在就是没法向其赋物理地址,我知道在ntddk中是可以的,有MmGetPhysicalAddress函数可直接调用,可该函数在WDM中却不支持,也找不到替换函数,不知哪位高手知道,请赐教,不胜感谢!
|
|
5楼#
发布于:2001-06-22 10:41
可以试试编个dll,直接访问IO端口
|
|
|
6楼#
发布于:2001-06-22 13:10
我在NT4.0中IoMapTransfer()和MmGetPhysicalAddress()来得到物理地址。根据书上所说在WDM中应该用Adapter对象的MapTransfer来得到物理地址,大概是这样:
AdapterObject->DmaOperations->MapTransfer(,,,,,)。我还没用过布置对不对。 |
|
|
7楼#
发布于:2001-06-22 22:57
首先我要说明一个误解,直接IO只有在一次传输的数据
量大于一个页面的时候相比BUFFER IO才有速度上的优势。 一个页面在X86下是4K。 另外,WIN9X下有SHELL_POST_MSG可以通知APP。 提问题的那个老弟我估计是在NT/2000系统下, 在这个系统下,不需要9X的那种函数。首先 考虑用异步IO。如果异步IO还是满足不了要求, 那么可以考虑用DRIVER和APP共享非分页内存 的方法,如果还是满足不了,那么NT/2000系统 基本上可以说,不适合做你要做的事情。 如果数据只在很短时间内需要采集,可以在ISR里面 查询。这也是一个方法。OSR的人就这么做过一个项目。 |
|
|
8楼#
发布于:2001-06-26 10:52
关于数据的实时采集,通过这几天的实验,我发现可以用事件通知的方式实现。具体是由应用程序通过DeviceIoControl传递一个Event的地址,驱动程序再调用ObReferenceObjectByHandle获取事件句柄。这样,我们在dpc例程中就可以调用KeSetEvent向用户程序发出事件通知。用户程序取数的方式是先WaitForSingleObject等待Event,然后调用ReadFile从设备RAM中读数。这种方法我试过,实时性还可以。
可是我还有一个问题,我上面的取数用的是缓冲I/O方式,METHOD_NEITHER方式也可以使用,但是,对于直接I/O方式,我还不知道如何使用。我是调用MmGetMdlVirtualAddress获得MDL的虚拟地址的,但是,这个虚拟地址是一个无效地址,无法使用RtlCopyMemory, 不知有谁能给我解答这个问题? 还有,huyg兄能否具体讲讲Driver和App共享非分页内存的方法? |
|