vrian
驱动牛犊
驱动牛犊
  • 注册日期2001-06-15
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1942回复:11

紧急求助!

楼主#
更多 发布于:2001-10-26 16:56
项目快结束,才发现这个问题.特请教各位多谢了!
环境是 win2000, VC60
我给一个ISA卡写了一个Driver,通过和App共享内存获得数据.
当中断到时,Driver通过Event通知App,App从共享内存获得数据,计算后App再实时显示曲线.
但现在问题是当通讯时,如果拖动App,App里的等待数据的线程会挂起,或者App运行时如果启动另一个大些程序,App也会丢失部分的数据!

请问您有好的办法吗?

最新喜欢:

flyfoxflyfox
丈夫自有冲天志,不向如来行处行!
peng-416
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-10-29 16:16
说白了你这样的驱动程序与应用程序同步的方法不可能实现.
你可以在驱动程序中将它写到文件中去,这样数据不会丢失,但是也不可能实现实时处理,因为Windows系统都不支持实时处理.
[peng-416 编辑于 2001-10-29 16:19]
vrian
驱动牛犊
驱动牛犊
  • 注册日期2001-06-15
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-10-30 11:02
我采用把App和等待线程的优先级提高的办法,使等待线程达到33级
情况好了一些,但还是有丢的!
如果把写文件放到driver中,那又如何实时显示呢?应用层和核心层文件能共享吗?
丈夫自有冲天志,不向如来行处行!
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2001-10-30 11:44
这种情况下本不允许再有其它的大程序的运行。
对于数据的丢失,你肯定问题出在app中而不是driver中。看看提高一下你driver的运行的IRQL试试。
对于共享内存,可申请两块或多块试试,注意不要一次申请太大的内存块。或者干脆去掉共享内存,直接将采样写入app传入的内存中
System Internals http://sys.xiloo.com
vrian
驱动牛犊
驱动牛犊
  • 注册日期2001-06-15
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2001-10-30 14:25
我说的共享内存是把数据采集板上的采集数据ROM转到App中的,
我试试你说的driver提高运行的IRQL!
先谢谢你!
丈夫自有冲天志,不向如来行处行!
ppl
ppl
驱动小牛
驱动小牛
  • 注册日期2001-06-13
  • 最后登录2006-05-21
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2001-10-30 15:22
 你可以先统计一下,是driver丢了数据,还是app丢了
 数据。
  我估计是app而不是driver
vrian
驱动牛犊
驱动牛犊
  • 注册日期2001-06-15
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2001-10-31 14:45
Driver没有采数,只是在DPC中重置Event通知App, App在去共享内存采数!
如果没有拖放,和其它事件,就没有数据的丢失!
提高IRQL好像没有用!
丈夫自有冲天志,不向如来行处行!
skysky
驱动小牛
驱动小牛
  • 注册日期2001-07-18
  • 最后登录2003-06-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2001-11-01 18:32
I had ever joint a project. The most important task is to
transfer the hardware data to user buffer(application buffer) and display it REALTIME.

We use PCI chip to transfer data. And the os is WIN2000.

To display data realtime in win2000, the most important thing is: transfer the data as quickly as you can.

As you say, you often lost your data. It don't not surprise me.We met the issue ever.

You problem can't be solved easily.
First of all, ISA is slower than PCI.
You can't change your hardware device, do you?

Tell you how we solve the problem:
1. Firstly we use copy to transfer data and we find we will lost much data.
2. Then we use master DMA to realize it.
It seems we succeed. But we meet many other issures. I won't talk much about it.

May you can change your device. Or you can move your data to user buffer by DMA method.
Raising the IRQL is also a working method.
Or map you ROM into user memory( Microsoft don't recomment it).

of course your PC should have enough memory.hehe,

In a word, if you can raise your transfer speed. I believe you will not lost any data.

Wish you best luck!
以德服人,以德服人
vrian
驱动牛犊
驱动牛犊
  • 注册日期2001-06-15
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2001-11-02 16:13
非常谢谢您的提示!
我的问题可能是在APP层,我正在用缓冲区试试看能不能提高App的效率!
再次感谢!
丈夫自有冲天志,不向如来行处行!
gxzbme
驱动牛犊
驱动牛犊
  • 注册日期2001-08-09
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2001-11-05 20:03
不用缓存,对事件的等待也会出问题。

os的任务多时,底层不停的KeSetEvent, but in app, no more time to process the WaitSingleObject function, thus, the
notification events have been lost....

not th isa card's issues.

u can refrence a examples :
debugprint monitor.  (app)
debugprint driver.   (driver)
debugprint listener. (data & message listener function in drivers)
 
here, u can find  the LIST_ENTRY structure is very useful  and powerful in the ADC driver(s). it is a soft FIFO no length limits!

FIFO: ( First in , First Out).

  
  

 
[gxzbme 编辑于 2001-11-05 20:05]
vrian
驱动牛犊
驱动牛犊
  • 注册日期2001-06-15
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2001-11-06 09:26
It's a good suggestion!
Can u tell me where I can get this examples ?  
Thanks again!
丈夫自有冲天志,不向如来行处行!
gxzbme
驱动牛犊
驱动牛犊
  • 注册日期2001-08-09
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2001-11-12 14:39
This is a example create by driverwork wizard:

driver :  Inputmsg.cpp,  Inputmsg.h;
          InputMsgDevice.cpp, InputMsgDeviceh
          function.h
App  :   Test_Inputmsg.cpp


please copy into vc6 for view.

u must recode the InputMsgRead dispatch rountine.
and delete the InputMsgWrite dispatch function.

u can create a system thread for read date from ur ISA card. in this thread, use a dead loop to insert new data
read from the card to the list tail, and in irp read dispatch rountine, remove a list node from the list head.

remeber, u must init the list and spinlock in device initial rountine.

have a good luck!

               gxzbme

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++



// Test_InputMsg.cpp

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>



typedef void VOIDFUNC();


void CloseIfOpen(void);

typedef struct _Event {
ULONG   ID;
char    buf[255];
} EventMsg;

HANDLE hDevice = INVALID_HANDLE_VALUE;

char *sLinkName = "\\\\.\\IkonInputMsgDevice0";


HANDLE OpenByName(void)
{
// Create a handle to the driver
return CreateFile(sLinkName,
 GENERIC_READ | GENERIC_WRITE,
 FILE_SHARE_READ,
 NULL,
 OPEN_EXISTING,
 0,
 NULL);
}

void CloseIfOpen(void)
{
if (hDevice != INVALID_HANDLE_VALUE)
{
// Close the handle to the driver
if (!CloseHandle(hDevice))
{
printf("ERROR: CloseHandle returns %0x.\n", GetLastError());
}
hDevice = INVALID_HANDLE_VALUE;
}
}


EventMsg eventmsg = {
0, "I am Monster!"
   };

EventMsg event1 = {
   1, " I am Gong xinzhou!"
   };
  
int __cdecl main(int argc, char *argv[])
{
int nArgIndex; // Walk through command line arguments
int nArgIncrement = 0;
int val;
ULONG nWritten,nRead;

printf("Test application Test_InputMsg starting...\n");

hDevice = OpenByName();
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("ERROR opening device: (%0x) returned from CreateFile\n", GetLastError());
Exit(1);
}
else
{
printf("Device found, handle open.\n");
}

// Parse the command line

printf("eventmsg:  ID=%2d, Buf=%s\n",eventmsg.ID,eventmsg.buf);
WriteFile(hDevice, &eventmsg, sizeof(EventMsg), &nWritten, NULL);


ReadFile(hDevice, &event1, sizeof(EventMsg), &nRead, NULL);

printf("event1:  ID=%2d, Buf=%s\n",event1.ID,event1.buf);
CloseIfOpen();

return 0;
}
////////////////////////////////////////////////////////////


// InputMsg.cpp


#define VDW_MAIN
#include <vdw.h>
#include "function.h"
#include "InputMsg.h"
#include "InputMsgDevice.h"

#pragma hdrstop("InputMsg.pch")

POOLTAG DefaultPoolTag('upnI');

KTrace t("InputMsg");

#pragma code_seg("INIT")

DECLARE_DRIVER_CLASS(InputMsg, NULL)

NTSTATUS InputMsg::DriverEntry(PUNICODE_STRING RegistryPath)
{
NTSTATUS status; // Status of device creation

t << "In DriverEntry\n";

UNREFERENCED_PARAMETER(RegistryPath);


int Unit;

Unit = 0;

InputMsgDevice* pInputMsgDevice;
pInputMsgDevice = new (
static_cast<PCWSTR>(KUnitizedName(L"InputMsgDevice", Unit)),
FILE_DEVICE_UNKNOWN,
static_cast<PCWSTR>(KUnitizedName(L"InputMsgDevice", Unit)),
0,
DO_BUFFERED_IO
)
InputMsgDevice();

if (pInputMsgDevice == NULL)
{
t << "Error constructing device InputMsgDevice" << EOL;
return STATUS_INSUFFICIENT_RESOURCES;
}

status = pInputMsgDevice->ConstructorStatus();
if (!NT_SUCCESS(status))
{
t << "Error creating device InputMsgDevice, status " << (ULONG) status << EOL;
delete pInputMsgDevice;
return status;
}

return STATUS_SUCCESS;
}



#pragma code_seg()


VOID InputMsg::Unload(VOID)
{
t << "Unload called\n";
KDriver::Unload();
}

// InputMsgDevice.cpp
// Implementation of InputMsgDevice device class

#include <vdw.h>

#include "InputMsg.h"
#include "InputMsgDevice.h"

#pragma warning(disable:4065) // Allow switch statement with no cases

extern KTrace t; // Global driver trace object


InputMsgDevice::~InputMsgDevice()
{
delete m_RegPath;
}

#pragma code_seg("INIT")

InputMsgDevice::InputMsgDevice(ULONG Unit) :
KDevice()
{
if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
t << "Failed to create device InputMsgDevice unit number " << Unit << " status " << (ULONG) m_ConstructorStatus << EOL;
return;
}
m_Unit = Unit;

m_RegPath = CreateRegistryPath(L"InputMsgDevice", Unit);
if (m_RegPath == NULL)
{
t << "Failed to create registry path\n";
m_ConstructorStatus = STATUS_INSUFFICIENT_RESOURCES;
return;
}

m_pDeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
m_pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

KeInitializeSpinLock(&EventListLock);
KeInitializeSpinLock(&ReadIrpLock);

InitializeListHead(&EventList);
ReadIrp = NULL;
}
#pragma code_seg()


VOID InputMsgDevice::InputMsgCancelIrp(KIrp I)
{
KIRQL irql;
KeAcquireSpinLock(&ReadIrpLock,&irql);
if( I = ReadIrp)
{
ReadIrp = NULL;
}
KeReleaseSpinLock(&ReadIrpLock,irql);

// Whatever Irp it is, just cancel it
I.Complete(STATUS_CANCELLED,0);
}




BOOLEAN InputMsgDevice::ReadEvent(KIrp I)
{
// Try to remove Event from EventList
PLIST_ENTRY pListEntry = ExInterlockedRemoveHeadList(&EventList, &EventListLock);
if( pListEntry==NULL)
return false;

// Get event as INPUTMSG_EVENT
PINPUTMSG_EVENT pEvent = CONTAINING_RECORD( pListEntry, INPUTMSG_EVENT, ListEntry);

// Get length of event data
ULONG EventDataLen = pEvent->Len;

// Copy data to I and complete it
RtlCopyMemory(I.BufferedReadDest(),pEvent->EventData, EventDataLen);
I.Information() = EventDataLen;

I.SetCancelRoutine(NULL);
I.Complete(STATUS_SUCCESS);

// Free event memory
ExFreePool(pEvent);
return true;
}


NTSTATUS InputMsgDevice::Read(KIrp I)
{
t << "Entering read, " << I;

// Always ok to read 0 elements
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.Complete(STATUS_SUCCESS);
}
NTSTATUS status = STATUS_SUCCESS;

////////////////////////////////////////////////////////////////////////////////
// Only one listening read allowed at a time.
KIRQL irql;
KeAcquireSpinLock(&ReadIrpLock,&irql);
if( ReadIrp!=NULL)
{
KeReleaseSpinLock(&ReadIrpLock,irql);
return I.Complete(STATUS_UNSUCCESSFUL);
}

// See if there's data available
if( ReadEvent(I))
{
KeReleaseSpinLock(&ReadIrpLock,irql);
return STATUS_SUCCESS;
}

// No event is available, queue this read Irp
ReadIrp = I;
KeReleaseSpinLock(&ReadIrpLock,irql);

// Mark Irp as pending and set Cancel routine
I.Information() = 0;

I.MarkPending(I.Status());

I.SetCancelRoutine(LinkTo(InputMsgCancelIrp) );

return STATUS_PENDING;

////////////////////////////////////////////////////////////////////
}


NTSTATUS InputMsgDevice::Write(KIrp I)
{
t << "Entering write, " << I;

if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.Complete(STATUS_SUCCESS);
}
NTSTATUS status = STATUS_SUCCESS;

///////////////////////////////////////////////////////////////////////////////////
ULONG   WriteLen = I.WriteSize(CURRENT);

// Copy write data into an event
ULONG Len = sizeof(LIST_ENTRY)+sizeof(ULONG)+WriteLen;
PINPUTMSG_EVENT pEvent = (PINPUTMSG_EVENT)ExAllocatePool(NonPagedPool,Len);
if( pEvent==NULL)
{
return I.Complete(STATUS_INSUFFICIENT_RESOURCES,0);
}

pEvent->Len = WriteLen;

RtlCopyMemory( pEvent->EventData, I.BufferedWriteSource(), WriteLen);

// Insert event into event list
ExInterlockedInsertTailList(&EventList,&pEvent->ListEntry,&EventListLock);

// If read pending, then read it
KIRQL irql;
KeAcquireSpinLock(&ReadIrpLock,&irql);
if( ReadIrp!=NULL)
if( ReadEvent(I))
{
ReadIrp = NULL;
}
KeReleaseSpinLock(&ReadIrpLock,irql);

///////////////////////////////////////////////////////////////

I.Information() = WriteLen;

return I.Complete(status);

}



NTSTATUS InputMsgDevice::Create(KIrp I)
{
t << "Entering Create, " << I;
I.Information() = 0;
return I.Complete(STATUS_SUCCESS);
}


NTSTATUS InputMsgDevice::Close(KIrp I)
{
t << "Entering Close, " << I;
I.Information() = 0;
return I.Complete(STATUS_SUCCESS);
}

// InputMsgDevice.h
//

#ifndef __InputMsgDevice_h__
#define __InputMsgDevice_h__

typedef struct _INPUTMSG_EVENT
{
LIST_ENTRY ListEntry;
ULONG Len;
UCHAR EventData[1];
} INPUTMSG_EVENT, *PINPUTMSG_EVENT;

class InputMsgDevice : public KDevice
{
public:
SAFE_DESTRUCTORS;
InputMsgDevice(ULONG Unit=0);
~InputMsgDevice();
public:
DEVMEMBER_DISPATCHERS

#ifdef __COMMENT_ONLY

virtual NTSTATUS Close(KIrp I); // COMMENT_ONLY
virtual NTSTATUS Create(KIrp I); // COMMENT_ONLY
virtual NTSTATUS Read(KIrp I);   // COMMENT_ONLY
virtual NTSTATUS Write(KIrp I); // COMMENT_ONLY
#endif

BOOLEAN ReadEvent(KIrp I);

// VOID InputMsgCancelIrp(KIrp Irp);

DEVMEMBER_CANCELIRP (InputMsgDevice, InputMsgCancelIrp)
protected:

ULONG m_Unit;
KUnitizedName * m_RegPath;

KIrp ReadIrp; // "Read queue" of 1 IRP

KSPIN_LOCK EventListLock;

KSPIN_LOCK ReadIrpLock; // Spin lock to guard access to ReadIrp

LIST_ENTRY EventList;

};


#endif // __InputMsgDevice_h__


// InputMsg.h
//
#ifndef __InputMsg_h__
#define __InputMsg_h__
  
#define EOL "\n"

class InputMsg : public KDriver
{
SAFE_DESTRUCTORS
public:
virtual  VOID Unload(VOID);
virtual  NTSTATUS DriverEntry(PUNICODE_STRING RegistryPath);

};

#endif // __InputMsg_h__







          



游客

返回顶部