5驱动程序模型和加载实验.docx
《5驱动程序模型和加载实验.docx》由会员分享,可在线阅读,更多相关《5驱动程序模型和加载实验.docx(27页珍藏版)》请在冰豆网上搜索。
5驱动程序模型和加载实验
实验五 驱动程序模型和加载实验
1.实验目的:
1.熟悉驱动程序的原理和功能;
2.熟悉流式接口驱动程序的结构;
3.掌握实现流式接口驱动的基本步骤;
4.掌握在PlatformBuilder编写流式接口驱动的方法。
2.实验任务:
1.构建一个Wince平台;
2.编写流式接口的驱动程序;
3.编写驱动测试程序;
4.运行驱动和测试程序,查看输出结果。
3.实验步骤:
1.启动PlatformBuilder
如图1,单击“开始”菜单,选择“所有程序”->“MicrosoftWindowsCE5.0”->“PlatformBuilder5.0”,启动PlatformBuilder。
启动界面如图2。
图1PlatformBuilder5.0位置
图2PlatformBuilder5.0启动界面
2.创建一个定制的操作系统设计方案
●选择“File”->“NewPlatform”,弹出“NewPlatformWizard”向导,选择“Next”;
●在Name文本框,输入“DriverModel”作为操作系统设计的名字;
在Path文本框,输入或选择你的操作系统设计方案放置的根目录的路径;默认“%_WINCEROOT%\PBWorkspaces\DriverModel”如图3,然后选择“Next”;
图3工作空间的名字和位置
●从可以获得的板级支持包列表(BSP)中,选择EMULATOR:
X86,如图4(在界面右侧的信息栏中显示该BSP的相关信息),然后选择“Next”;
图4选择板级支持包
●从可以获得的操作系统设计模板中,选择“EnterpriseWebPad”,如图5,然后选择“Next”;
图5选择设计模板
●删除“Applications&Media”选项,如图6,然后选择“Next”;
图6删除“Applications&Media”选项
●删除“Networking&Communications”选项,如图7,然后选择“Next”;
图7删除“Networking&Communications”选项
●默认通告,然后选择“Next”;
●点击”Finish”,完成新平台向导,如图8。
图8完成新平台向导
3.编写流式接口的驱动程序
●在PlatformBuilder中选择“File”->“NewProjectorFile”,创建一个“WindowsCEDynamiclinklibrary”项目,项目的名称填写“MyDriver”,如图9;
图9“NewProjectorFile”对话框
●向导的第一步,默认,然后点击“Next”;
●向导的第二步选择“ASimpleWindowsCEDLL”,如图10,然后点击“Next”。
PlatformBuilder会为我们生成DLL框架代码。
图10Step2of3
●向导的第三步默认,然后点击“Finish”。
●在WorkSpace工作区,打开FileView,找到文件MyDriver.cpp,位置如图11。
双击打开后,在编辑区修改PlatformBuilder生成的DllMain函数,如下:
BOOLAPIENTRYDllMain(HANDLEhModule,
DWORDul_reason_for_call,
LPVOIDlpReserved
)
{
switch(ul_reason_for_call)
{
caseDLL_PROCESS_ATTACH:
OutputDebugString(L"MyDriver-DLL_PROCESS_ATTACH\n");
break;
caseDLL_PROCESS_DETACH:
OutputDebugString(L"MyDriver-DLL_PROCESS_DETACH\n");
break;
caseDLL_THREAD_ATTACH:
OutputDebugString(L"MyDriver-DLL_THREAD_ATTACH\n");
break;
caseDLL_THREAD_DETACH:
OutputDebugString(L"MyDriver-DLL_THREAD_DETACH\n");
break;}
returnTRUE;
}
图11文件MyDriver.cpp位置
●添加流式接口驱动的导出函数前置声明,放到文件MyDriver.cpp,添加到DllMain函数之前,如下:
DWORDDEM_Init(LPCTSTRpContext,LPCVOIDlpvBusContext);
BOOLDEM_Deinit(DWORDhDeviceContext);
DWORDDEM_Open(DWORDhDeviceContext,DWORDAccessCode,DWORDShareMode);
BOOLDEM_Close(DWORDhOpenContext);
BOOLDEM_IOControl(DWORDhOpenContext,DWORDdwCode,PBYTEpBufIn,DWORDdwLenIn,PBYTEpBufOut,DWORDdwLenOut,PDWORDpdwActualOut);
voidDEM_PowerUp(DWORDhDeviceContext);
voidDEM_PowerDown(DWORDhDeviceContext);
DWORDDEM_Read(DWORDhOpenContext,LPVOIDpBuffer,DWORDCount);
DWORDDEM_Write(DWORDhOpenContext,LPCVOIDpBuffer,DWORDCount);
DWORDDEM_Seek(DWORDhOpenContext,longAmount,WORDType);
#defineIOCTL_DRIVER_DEMO42
//NotexposedbytheDeviceDriver
voidDBGOut(DWORDdwValue);
HANDLEhMem=NULL;
DWORDdwCount;
●添加导出函数的具体实现,放到文件MyDriver.cpp,代码如下:
DWORDDEM_Init(LPCTSTRpContext,LPCVOIDlpvBusContext)
{
OutputDebugString(L"MyDriver-DEM_Init-Context:
");
OutputDebugString(pContext);
OutputDebugString(L"\n");
OutputDebugString(L"MyDriver-~DEM_Init\n");
return0x1234;
}
BOOLDEM_Deinit(DWORDhDeviceContext)
{
OutputDebugString(L"MyDriver-DEM_Deinit\n");
OutputDebugString(L"MyDriver-~DEM_Deinit\n");
returnTRUE;
}
DWORDDEM_Open(DWORDhDeviceContext,DWORDAccessCode,DWORDShareMode)
{
OutputDebugString(L"MyDriver-DEM_Open\n");
OutputDebugString(L"hDeviceContext-");
DBGOut(hDeviceContext);
OutputDebugString(L"\n");
OutputDebugString(L"MyDriver-~DEM_Open\n");
return0x5678;
}
BOOLDEM_Close(DWORDhOpenContext)
{
OutputDebugString(L"MyDriver-DEM_Close\n");
OutputDebugString(L"hOpenContext-");
DBGOut(hOpenContext);
OutputDebugString(L"\n");
OutputDebugString(L"MyDriver-~DEM_Close\n");
returnTRUE;
}
BOOLDEM_IOControl(DWORDhOpenContext,DWORDdwCode,PBYTEpBufIn,DWORDdwLenIn,PBYTEpBufOut,DWORDdwLenOut,PDWORDpdwActualOut)
{
OutputDebugString(L"MyDriver-DEM_IOControl\n");
OutputDebugString(L"hOpenContext-");
DBGOut(hOpenContext);
OutputDebugString(L"\n");
switch(dwCode){
caseIOCTL_DRIVER_DEMO:
{
OutputDebugString(L"DRIVERDEMOIOCTL...\n");
//reversethestring...
HANDLEhTemp=LocalAlloc(LPTR,dwLenIn+1);
memset(hTemp,0x00,dwLenIn+1);
TCHAR*tcOut=(TCHAR*)hTemp;
TCHAR*tcIn=(TCHAR*)pBufIn;
DWORDdwChars=dwLenIn/2;
for(DWORDx=0;xtcOut[x]=tcIn[dwChars-x-1];
}
memcpy(pBufOut,hTemp,dwLenIn);
LocalFree(hTemp);
*pdwActualOut=dwLenIn;
}
break;
default:
OutputDebugString(L"UnknownIOCTL\n");
break;
}
OutputDebugString(L"MyDriver-~DEM_IOControl\n");
returnTRUE;
}
voidDEM_PowerUp(DWORDhDeviceContext)
{
OutputDebugString(L"MyDriver-DEM_PowerUp\n");
OutputDebugString(L"hDeviceContext-");
DBGOut(hDeviceContext);
OutputDebugString(L"\n");
OutputDebugString(L"MyDriver-~DEM_PowerUp\n");
}
voidDEM_PowerDown(DWORDhDeviceContext)
{
OutputDebugString(L"MyDriver-DEM_PowerDown\n");
OutputDebugString(L"hDeviceContext-");
DBGOut(hDeviceContext);
OutputDebugString(L"\n");
OutputDebugString(L"MyDriver-~DEM_PowerDown\n");
}
DWORDDEM_Read(DWORDhOpenContext,LPVOIDpBuffer,DWORDCount)
{
DWORDdwRetCount=0xffff;//defaulttoerror
OutputDebugString(L"MyDriver-DEM_Read\n");
OutputDebugString(L"hOpenContext-");
DBGOut(hOpenContext);
OutputDebugString(L"\n");
if(NULL!
=hMem){
dwRetCount=dwCount;
memcpy(pBuffer,hMem,dwCount);
}
OutputDebugString(L"MyDriver-~DEM_Read\n");
returndwRetCount;
}
DWORDDEM_Write(DWORDhOpenContext,LPCVOIDpBuffer,DWORDCount)
{
OutputDebugString(L"MyDriver-DEM_Write\n");
OutputDebugString(L"hOpenContext-");
DBGOut(hOpenContext);
OutputDebugString(L"\n");
if(NULL!
=hMem){
LocalFree(hMem);
}
hMem=LocalAlloc(LPTR,Count);
memcpy(hMem,pBuffer,Count);
dwCount=Count;
OutputDebugString(L"MyDriver-~DEM_Write\n");
returnCount;
}
DWORDDEM_Seek(DWORDhOpenContext,longAmount,WORDType)
{
OutputDebugString(L"MyDriver-DEM_Seek\n");
OutputDebugString(L"hOpenContext-");
DBGOut(hOpenContext);
OutputDebugString(L"\n");
OutputDebugString(L"MyDriver-~DEM_Seek\n");
return0;
}
voidDBGOut(DWORDdwValue)
{
TCHARtcTemp[10];
wsprintf(tcTemp,L"%ld",dwValue);
OutputDebugString(tcTemp);
}
●添加导出函数的定义。
在PlatformBuilder菜单中,选择File->NewProjectorFile->Files->TextFile,文件名叫“MyDriver.def”,如图12,弹出的对话框,选择“是”。
图12NewProjectorFile
MyDriver.def内容如下:
LIBRARYMyDriver
EXPORTS
DEM_Init
DEM_Deinit
DEM_Open
DEM_Close
DEM_IOControl
DEM_PowerUp
DEM_PowerDown
DEM_Read
DEM_Write
DEM_Seek
本程序只是实现流式驱动的接口,并没有真正同硬件交互。
●在WorkSpace的ParameterView中打开project.reg,在文件中添加如下部分:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Sample]
"Dll"="mydriver.Dll"
"Prefix"="DEM"
"Index"=dword:
1
"Order"=dword:
0
"FriendlyName"="DemoDriver"
"Ioctl"=dword:
0
提示:
这段注册表信息告诉系统,在系统启动的时候把mydriver.dll加载到device.exe,驱动的前缀是DEM,下标索引是1,这样,我们就可以使用CreateFile(L”DEM1:
”……)这样的方式来访问驱动程序了。
4.编写驱动测试程序
●在PlatformBuilder中选择“File”->“NewProjectorFile”,创建名为“MyApp”的“典型HelloWorld”WCEApplication。
●打开”MyApp”工程,选择”ResouceView”,在”MyAppresources”点右键->”Insert..”->”Menu”,新建一个菜单项。
添加菜单项如下图13所示。
菜单项的ID如表1所示。
图13File菜单
表一菜单项ID
Caption
ID
Exit
ID_FILE_EXIT
Write
ID_DRIVER_WRITE
Read
ID_DRIVER_READ
IoControl
ID_DRIVER_IOCTL
●打开MyApp工程目录下的MyApp.cpp文件,将其代码修改如下:
//MyApp.cpp:
Definestheentrypointfortheapplication.
//
#include"stdafx.h"
#include"resource.h"
#include
#pragmacomment(lib,"commctrl")
#defineMAX_LOADSTRING100
#defineIDC_CMDBAR0x101
HWNDhWndCmdBar;
voidWriteToDriver();
voidReadFromDriver();
voidHandleIOCTL();
#defineIOCTL_DRIVER_DEMO42
//GlobalVariables:
HINSTANCEhInst;//currentinstance
TCHARszTitle[MAX_LOADSTRING];//Thetitlebartext
TCHARszWindowClass[MAX_LOADSTRING];//Thetitlebartext
//Forwarddeclarationsoffunctionsincludedinthiscodemodule:
ATOMMyRegisterClass(HINSTANCEhInstance);
BOOLInitInstance(HINSTANCE,int);
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
voidWriteToDriver()
{
DWORDdwWritten;
TCHAR*tcString=L"DemoString...";
HANDLEhDrv=CreateFile(L"DEM1:
",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hDrv){
OutputDebugString(L"FailedtoopenDriver...\n");
}else{
WriteFile(hDrv,(LPVOID)tcString,lstrlen(tcString)*sizeof(TCHAR),&dwWritten,NULL);
}
CloseHandle(hDrv);
}
voidReadFromDriver()
{
DWORDdwRead;
TCHARtcTemp[30];
HANDLEhDrv=CreateFile(L"DEM1:
",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hDrv){
OutputDebugString(L"FailedtoopenDriver...\n");
}else{
memset(tcTemp,0x00,30*sizeof(TCHAR));
ReadFile(hDrv,tcTemp,30,&dwRead,NULL);
MessageBox(NULL,tcTemp,L"DemoData",MB_OK);
}
CloseHandle(hDrv);
}
voidHandleIOCTL()
{
HANDLEhDrv=CreateFile(L"DEM1:
",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
TCHARtcBuffer[10];
DWORDdwBytesReturned;
lstrcpy(tcBuffer,L"Hello");
BOOLbRet=DeviceIoControl(
hDrv,
IOCTL_DRIVER_DEMO,
tcBuffer,
lstrlen(tcBuffer)*sizeof(TCHAR),
tcBuffer,
lstrlen(tcBuffer)*sizeof(TCHAR),
&dwBytesReturned,
NULL);
MessageBox(NULL,tcBuffer,L"IOCTLTest",MB_OK);
CloseHandle(hDrv);
}
intWINAPIWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPTSTRlpCmdLine,
intnCmdShow)
{
//TODO:
Placecodehere.
MSGmsg;
HACCELhAccelTable;
//Initializeglobalstrings
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadString(hInstance,IDC_MyApp,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);
//Performapplicationinitialization