Wince边做边学8

来源:互联网 发布:淘宝卖家信誉度怎么看 编辑:程序博客网 时间:2024/06/07 01:29
在上次的边做边学中,我们了解到了内置的设备驱动程序的架构,因为各种不同类别的内置驱动程序要实现不同的接口,因此在实现起来就非常有针对性,也不利于演示。这次我们继续了解另一种驱动程序——流接口驱动程序的特点及其实现方法。
    流接口驱动程序是在应用程序层采用标准的文件操作APIS来调用设备的,最常见的就是串口,我们可以使用CreateFile()函数来打开一个串口,然后通过ReadFile(),WriteFile()函数来读写串口,很显然,串口就是一种流接口的驱动程序。这类驱动程序的特点就是有着统一的接口函数,设备端一般都较简单,以数据提供者为主。
    标准的流接口是如下的一组函数,我们先来看一下这组函数的基本外观:
    1、HANDLE XXX_Init(LPCTSTR pContext,LPCVOID lpvBusContext);
       这个函数是在设备管理程序通过ActiveDeviceEx()函数激活设备时被系统调用的。它的主要功能是初始化驱动程序中用到的资源,对I/O地址空间和内存进行映射等。
    2、BOOL XXX_Deinit(DWORD hDeviceContext);
       这个函数是在设备管理程序通过DeactivateDevice()函数卸载设备时被系统调用的,它的主要功能是回收驱动程序中用到的资源。
    3、DWORD XXX_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode);
       这个函数是在应用程序通过CreateFile()函数打开设备时调用的。
    4、BOOL XXX_Close(DWORD hOpenContext);
       这个函数是在应用程序通过CloseHandle()函数关闭句柄时调用的。
    5、DWORD XXX_Read(DWORD hOpenContext,LPVOID pBuffer,DWORD Count);
       这个函数是在应用程序通过ReadFile()函数读取设备时调用的。
    6、DWORD XXX_Write(DWORD hOpenContext,LPCVOID pBuffer,DWORD Count);
       这个函数是在应用程序通过WriteFile()函数向设备写入数据时调用的。
    7、DWORD XXX_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut);
       这个函数是在应用程序通过DeviceIOControl()函数向设备发送控制字时调用的。
    8、void XXX_PowerUp(DWORD hDeviceContext);
       这个函数是在向设备恢复供电的时候调用的。
    9、void XXX_PowerDown(DWORD hDeviceContext);
       这个函数是在设备断电的时候调用的。

    上述函数中的XXX部分是在注册表中注册此设备驱动程序的时候Perfix注册表项的值。例如串口,则用Com,并口则用LTP等等。只要一个DLL中针对特定设备实现了上述接口并且正确在注册表中注册,那么就可以在程序中通过那些文件API函数来访问此设备。下面我们就一起在PB5中按上述接口模拟一个设备。设备的名字就叫做TTT吧。
    运行PB5,打开上次做的平台,在文件菜单中执行"New Project or File"命令,新建一个"WCE Dynamic-Link Library"项目,输入项目名字为"Test"。在向导的第一步中输入必要的信息(此处不输也可以,这些信息可供向导自动生成一个README.TXT文件,不过还是写上好,以免以后忘了),在下一步中选择一个空项目,完成。
    在新的源程序文件中输入以下程序:
// test.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "memory.h"
#include "windows.h"

HANDLE* hDevice;
#define BUFSIZE 256
WCHAR buffer[BUFSIZE];

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

HANDLE TTT_Init(LPCTSTR pContext,LPCVOID lpvBusContext)
{
hDevice=(HANDLE*)LocalAlloc(LPTR,sizeof(HANDLE));
memset(buffer,0,sizeof(WCHAR)*BUFSIZE);
return hDevice;
}

BOOL TTT_Deinit(DWORD hDeviceContext)
{
LocalFree(hDevice);
return TRUE;
}

DWORD TTT_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode)
{
if (!hDeviceContext)
return FALSE;
return TRUE;
}

BOOL TTT_Close(DWORD hOpenContext)
{
if (!hOpenContext)
return FALSE;
return TRUE;
}

DWORD TTT_Read(DWORD hOpenContext,LPVOID pBuffer,DWORD Count)
{
DWORD dwret=min(BUFSIZE,Count);
wcsncpy((LPWSTR)pBuffer,buffer,dwret);
return dwret;
};

DWORD TTT_Write(DWORD hOpenContext,LPCVOID pBuffer,DWORD Count)
{
DWORD dwret=min(BUFSIZE,Count);
wcsncpy(buffer,(LPWSTR)pBuffer,dwret);
return dwret;
}

DWORD TTT_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,
DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
return TRUE;
}

void TTT_PowerUp(DWORD hDeviceContext)
{
return;
}

void TTT_PowerDown(DWORD hDeviceContext)
{
return;
}


    编译,然后编译该test文件夹下的test.def文件,将这些实现的接口函数导出:
LIBRARY TEST.DLL

EXPORTS

TTT_Init
TTT_Deinit
TTT_Open
TTT_Close
TTT_PowerUp
TTT_PowerDown
TTT_IOControl
TTT_Read
TTT_Write


    同时编辑此文件夹下的test.reg文件,加入必要的注册表项:
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/test]
"DeviceArrayIndex"=dword:0
"Prefix"="TTT"
"Dll"="test.Dll"
"Order"=dword:20

    好了,一个TTT设备的流接口驱动就写好了,从中可以看到,在写驱动的时候比PB4要更加清晰,在源程序文件夹中的DEF文件,REG文件,BIB文件,DB文件,DAT文件和编译链接时需要的BAT文件都被PB生成好了,开发人员只要作些必要的修改即可以,非常方便。
    接下来,为了测试我们的驱动程序是否可以正常工作,还需要写一个测试程序,再次为平台新建一个WCE应用程序项目TestTTT,写入如下代码并编译为EXE文件:
#include "stdafx.h"
#include "windows.h"

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.

HANDLE handle=CreateFile(_T("TTT1:"),GENERIC_READ|GENERIC_WRITE,0,
NULL,OPEN_EXISTING,0,NULL);
ASSERT(handle);
DWORD ret=0;
TCHAR* pstr=_T("This is a TEST of TTT Driver");
WriteFile(handle,pstr,(_tcslen(pstr)+1)*sizeof(TCHAR),&ret,NULL);
TCHAR ReadStr[256];
memset(ReadStr,0,sizeof(TCHAR)*256);
ret=0;
ReadFile(handle,ReadStr,sizeof(ReadStr),&ret,NULL);
MessageBox(NULL,ReadStr,_T("Test"),MB_OK);
CloseHandle(handle);
return 0;
}


    好了,一切准备就绪,重新编译平台并下载到设备上运行,在Windows文件夹(修改文件夹选项,把所有的复选框全去掉才能看到隐藏的和系统文件)下可以找到test.dll文件和TestTTT.exe文件,运行后者,结果如图:




    很简单吧,你只要在上述的接口中访问你的设备端口读写数据就可以了,我只是举个例子,希望能对你有所启发,对于驱动程序部分的内容,就先告一段落吧,继续关注后续文章吧!

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新卖的号码有人注册过支付宝怎么办 我的号码被别人注册了支付宝怎么办 别人用我的号码注册了支付宝怎么办 打开支付宝进入到淘宝的界面怎么办 我的手机号注销了支付宝账号怎么办 微博绑定的支付宝账号注销了怎么办 闲鱼买家申请退款卖家不同意怎么办 微信与手机旧版本不一致怎么办 在应用宝里下载微信老是失败怎么办 使用u盘储存视频显示不兼容怎么办 支付宝下载显示与存在不兼容怎么办 cpu与64位系统不兼容怎么办 微信版本低登录不了怎么办苹果手机 手机版本低登录不了微信怎么办? 进入微信公众号显示登录失败怎么办 安卓系统手机亮度调到最低怎么办 阿里妈妈买家号虚假交易违规怎么办 淘宝商让我修改追评叫我怎么办 红冲金额大于了当月的销售额怎么办 淘宝买家号虚假交易评价删除怎么办 淘宝卖的宝贝电话写错了怎么办 邮政快递都揽件了一直不运输怎么办 应用宝里面的安装包安装不了怎么办 苹果平板电脑充电接口坏了怎么办 读书郎平板电脑开不了机怎么办 平板电脑死机开不了机了怎么办 欧灵平板电脑忘记图密解锁怎么办 淘宝没货发给人被投诉了怎么办 淘宝店铺既不能开又不能注销怎么办 妻子被骗五万疑似被洗脑我该怎么办 奖虫账号和密码不匹配怎么办 开淘宝店余额宝里的钱怎么办 京东找不到所有宝贝的链接了怎么办 淘宝店链接改了标题没流量怎么办 淘宝手淘搜索自然流量少怎么办 4个月宝贝不食欲下降怎么办 淘宝商家预售时间到了不发货怎么办 淘宝修改类目被处置管控了怎么办 淘宝换手机号是已经注册了的怎么办 闲鱼违规把我淘宝店铺冻结了怎么办 开网店店主想买自己的东西怎么办