您的位置:首页 > 其它

驱动程序和应用程序之间通信(ForWinCE)(转载)

2008-12-25 09:38 344 查看
WinCE上驱动程序的模型相对比较简单,实现一个驱动程序不是什么难事。尽管如此,本文还是实现了一个比较通用一点的通讯接口。

应用程序发给信息驱动程序有两种方式,同步调用和异步调用。
同步调用能够让驱动程序立即处理应用程序的请求,并返回驱动程序处理后的结果。
如:

#define MSG_TYPE_TEST_1 0x00000000
#define MSG_TYPE_ICMP_PACKET 0x00000001

#pragma pack(push, 1)
typedef struct __IO_MESSAGE
{
ULONG Type;
ULONG Length;

union
{
struct
{
double x;
double y;
}Test_1;

struct
{
UCHAR MiniPacket[128];
}Icmp_Packet;

// All other messages add here

}value;
}IO_MESSAGE, *PIO_MESSAGE;
#pragma pack(pop)

#include <windows.h>
#include "ioexample.h"
#include "ioapp.h"

VOID SendMessageWithResult()
{
//
// First of all, open the device
//
if(!IO_Open())
return;

//
// Build message
//
IO_MESSAGE Msg;

Msg.Type = MSG_TYPE_TEST_1;
Msg.Length = sizeof(Msg.value.Test_1);
Msg.value.Test_1.x = 3.0;
Msg.value.Test_1.y = 4.0;

//
// Call API to send, IO_SendEx run sync and then return a result.
//
UCHAR lpOutBuf[8];
DWORD BytesReturned;
BOOL bRet = IO_SendEx((PTLV)&Msg, TLV_LENGTH(&Msg), lpOutBuf, 8, &BytesReturned);
if(!bRet) // If return FALSE, BytesReturned is error code.
{
switch(BytesReturned)
{
case IO_ERROR_INVALID_LENGTH:
break;
case IO_ERROR_UNKNOWN:
break;
}
}

//
// Then we get the result
//
double z = *(double*)lpOutBuf;

//
// When we quit application, don't forget close device.
//
IO_Close();
}

异步调用不需要结果返回,调用立即返回。对驱动程序的请求会随后执行。
如:

VOID SendMsg()
{
//
// First of all, open the device
//
if(!IO_Open())
return;

//
// Build message
//
IO_MESSAGE Msg;

Msg.Type = MSG_TYPE_TEST_1;
Msg.Length = sizeof(Msg.value.Test_1);
Msg.value.Test_1.x = 3.0;
Msg.value.Test_1.y = 4.0;

//
// Call API to send, IO_SendEx run async.
//
BOOL bRet = IO_Send((PTLV)&Msg, TLV_LENGTH(&Msg)); // if we give sizeof(Msg) is also OK.
if(!bRet) // If return FALSE, something error.
{
}

//
// When we quit application, don't forget close device.
//
IO_Close();
}

驱动程序也可以通知应用程序,应用程序检测到通知事件后,可以取回驱动程序发送给应用程序的请求。

如:

VOID ThreadForReceive()
{
//
// First of all, open the device
//
if(!IO_Open())
return;

//
// setup a receive event for driver
//
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(hEvent == NULL)
return;

IO_InitializeReceiveEvent(hEvent);

//
// We can wait for this event and then receive one or more times
//
while(1)
{
DWORD dRet = WaitForSingleObject(hEvent, INFINITE);
if(dRet == WAIT_OBJECT_0)
{
DWORD NumbersRemained;
IO_MESSAGE OutMessage;
BOOL bRet = IO_Receive((PTLV)&OutMessage, sizeof(IO_MESSAGE), &NumbersRemained);
if(bRet == FALSE) // if return false, numbersremained is error code
{
}
else
{

}

for(int i=0; i<NumbersRemained; i++)
{
DWORD temp;
bRet = IO_Receive((PTLV)&OutMessage, sizeof(IO_MESSAGE), &temp);
}
}

// We can test here whether main process let us quit
//if(WAIT_OBJECT_0 == WaitForSingalObject(hQuitEvent, 0))
// break;

// As a test, any way we should break here
break;
}

// Free them
IO_RemoveReceiveEvent();
CloseHandle(hEvent);

//
// When we quit application, don't forget close device.
//
IO_Close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: