阅读:1289回复:11
分太多了,放分了,100,这种情况怎么来实现
我是用DS写的ISA的NT试的驱动,现在要采用中断方式传输数据,大概是这样的:数据传输方向是从主机到板子,当板子上的FIFO空的时候给主机发中断,驱动进入中断处理例程,延迟进入中断延迟调用,在中断延迟调用里,驱动给FIFO写数据。现在的问题就是驱动怎么样和应用层握手,得到应用层传来数据的问题,(为了节省时间,不打算采用以前那种事件通知的办法:应用先传一个事件对象给驱动,然后用一个线程等待,当驱动的中断延迟调用中把时间设置为有效的时候,应用开始给驱动传数据,写FIFO),打算这么办,但我不太明白,我驱动具体怎么来处理:应用层通过DEVICEIOCTL把应用层开辟的存放发给FIFO的数据的缓冲区的地址传给驱动,驱动把这个地址保存起来,然后就是前面说的在中断的延迟调用里,直接写FIFO,不知道高手们,有没有这么干过??
驱动里具体怎么来做? 急切盼望! |
|
|
沙发#
发布于:2003-08-21 17:17
那你就是想共享内存的方式罗?
可以参考一下。 |
|
|
板凳#
发布于:2003-08-22 15:50
那你就是想共享内存的方式罗? 我看了大虾提供的这篇文章,前面说的是应用分配缓冲,然后传到驱动,驱动中把缓冲区从用户模式转换成核心模式,直接操作这个缓冲区就可以了。这是最普遍的方法,一般用DEVICEIOCTL和REDADFILE,WRITEFIEL都能来实现这个。后面说的是在驱动中分配缓冲,然后把地址传给应用。 我现在不需要驱动分配缓冲,是想操作应用分配的缓冲,但不是在DEVICEIOCTL例程里操作,而是要在中断的延迟例程里操作应用分配的缓冲区,把缓冲区里的数据写给端口。 请教,这两个例程怎么衔接?? |
|
|
地板#
发布于:2003-08-24 14:17
人好少啊!
周末大家都休息??? |
|
|
地下室#
发布于:2003-08-25 09:10
刚才和做应用的人协调了一下,他发DEVICEIOCTL请求给我,传下来的缓冲区指针指向要发给我的数据。我在相应的DEVICEIOCTL分发例程里不能操作缓冲区里的数据,要在板子上的 FIFO空的时候发来的中断的延迟处理例程里,我把应用发给我的数据写到FIFO里,请问,各位大虾,我在DEVICEIOCTL的分发例程里怎么做???
很急切! |
|
|
5楼#
发布于:2003-08-25 12:08
有个小小的疑问:你真的把那篇文章仔细看了?
|
|
6楼#
发布于:2003-08-25 14:13
我只看了前面中讲到的在应用层分配缓冲,然后通过DEVICEIOCTL传给驱动这部分,我感觉这个就是最普通的应用调用驱动的形式。
我现在的目的是在分发例程里不处理应用层传下来的数据,而是要把这些数据放在中断的延迟调用例程里来实现,但应用给我的数据我在驱动中还不能直接分配非分页内存保存(因为数据量很大,不可能在驱动层分配很大的内存),我想在分发例程里,我把应用层传下来带有数据的地址保存好,然后在中断延迟调用里从这个地址里写数给端口,我上午做了实验,一到中断的延迟调用例程,就死机,发生分页错误,而且我在分发例程里保存好的地址值在这里变成了0x00000000. 怎么回事? |
|
|
7楼#
发布于:2003-08-25 15:01
刚才又把程序改了,现在地址可以正确传递了,也就是在分发例程里保存的缓冲区的地址,我在中断延迟调用里照样可以操作。应用调用驱动把40个数:1,2,3,。。。。40传递到驱动中,驱动里的分发例程并不保存这40个数,而是保存存放这40个数的地址。分发例程返回后,中断到来,在中断的延迟调用里,操作分发例程保存的地址,但发现缓冲区的数据全是0xdd(我是PUCHAR类型缓冲),也就是分发例程结束后,缓冲区里的数据也就随着改变了,是不是这个意思?
怎么办?? |
|
|
8楼#
发布于:2003-08-25 18:25
自己顶了!
|
|
|
9楼#
发布于:2003-08-25 20:15
我的程序是这样的:我的设备类的头文件:MYDEVICE.h有:
。。。 。。。 。。。 public: PUCHAR PUF; ULONG L; 。。。 。。。 。。。 在我的设备类主文件里MYDEVICE.cpp里: 驱动传给应用缓冲区的分发例程里: MYDEVICE::ADDRESS_IOCTL_HANDLER(KIrp I) { NTSTATUS status; KMemory Mem(I.Mdl()); PUF=(PUCHAR)Mem.MapToSystem(); L=(ULONG)PUF; t<<\"映射后的地址是\"<<L<<\"\\n\"; ////事先在应用中的输出缓冲区里存入10个数:1,2,3。。。。10。 for(ULONG i=0;i<10;i++) { t<<\"应用层传过来的数据是:\"<<((PUCHAR)L)<<\"\\n\"; } //// 从打印出的信息看,能看到1,2,3。。。。10。在这里驱动层能正确接收应用传过来的数据。 ...... ...... ...... } 在中断延迟处理例程里: MYDEVICE::DpcForIsr( ) { ...... ...... ...... t<<\"在延迟例程里看到的映射地址\"<<L<<\"\\N\"; //程序运行的时候发现在这里看到的地址和在分发例程里的地址是一致的。 for(ULONG i=0;i<10;i++) { t<<\"应用层传过来的数据是:\"<<((PUCHAR)L)<<\"\\n\"; } //但在这里,却发现得到的数都是:0xdd; 不知道是怎么回事,哪位大虾给讲讲。 [编辑 - 8/26/03 by libin2309] |
|
|
10楼#
发布于:2003-08-25 21:48
If METHOD_DIRECT is used, the user buffer will be locked into memory. The driver will also need to call MmGetSystemAddressForMdlSafe() to map the described data buffer into kernel virtual address space. An advantage of this method is that the driver can access the shared memory buffer from an arbitrary process context, and at any IRQL.
|
|
11楼#
发布于:2003-08-26 08:56
更正:前面我说的程序里两个for 循环里应该都是:((PUCHAR)L)的后面应该有个中括号,里面是i.
arthurtu大虾, 我看了这段话,但还是不能理解为什么我在中断的延迟调用例程里看到的数据和在分发例程里看到的不一样,怎么做,才能保持数据的一致?? 急切! [编辑 - 8/26/03 by libin2309] |
|
|