WinCE第一个模拟流接口驱动

来源:互联网 发布:网络统考英语b 编辑:程序博客网 时间:2024/05/24 01:51

由于模拟流接口驱动,不涉及具体的硬件平台,整个过程在Windows中模拟。

 

BSP:SMDK2410

 

1.首先写一个简单的驱动,即一个DLL,实现规定的几个流接口标准函数。(可以用Windows CE Stream Driver Wizard程序生成)
2.把上面的工程拷到WINCE500/PLATFORM/SMDK2410/SRC/DRIVERS下面,并修改dirs文件。dirs中指明了要编译且添加到最终镜像中的各个目录。
3.修改Parameters View选项卡Emulator下的platform.reg
[HKEY_LOCAL_MACHINE/drivers/BuiltIn/SimpleDriver]
   "Dll" = "SimpleDriver.dll"
   "Prefix" = "DRV"
   "Index" = dword:1
   "Order" = dword:0
   "FriendlyName" = "SimpleDriver"
   "Icotl" = dword:0
4.修改修改Parameters View选项卡Emulator下的platform.bib。该文件表示最终被Copy到镜像中的文件(默认指定的文件应该出现在WCE的windows/目录下)
    SimpleDriver.dll      $(_FLATRELEASEDIR)/SimpleDriver.dll          NK  SH
5.生成Emulator镜像
6.使用Platform Builder新建一个APPlication,TestSimpleDriver

在新建程序WinMain中添加:
 HANDLE m_hDrv;
 WCHAR str[200];
 m_hDrv=CreateFile(L"DRV1:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
 if(m_hDrv==INVALID_HANDLE_VALUE)
 {
  int nRet=GetLastError();
  _itow(nRet,str,10);
  MessageBox(NULL,str,L"F",MB_OK);
  MessageBox(NULL,L"DRV",L"F",MB_OK);
 }
 else
  MessageBox(NULL,L"CreateFile Succeed",L"S",MB_OK);
 注意:一定是DRV1:,要有1和冒号
7.单独编译Application,把application共享到Emulator即可运行Application
也可以这样子:
下面的方法会在最终的镜像中加入对应的文件和应用程序:
修改platform.bib文件:
如下图所示,双击platform.bib文件,并在该文件尾部添加如下内容:
SimpleDriver.dll      E:/EVC/TestDRV/ARMV4Re1/testdrv.dll NK SH
TestSimpleDriver. exe  E: /EVC/TestDRVApp/ARMV4Dbg/testdrv. exe NK  U
通过这种方法就可以使用EVC编写驱动和测试程序,在加入到PB中了,而不用使用PB来编写驱动和测试程序了
8.查看运行状况.当wince系统启动完毕之后,在PB的tool菜单下,选择Remote Process Viewer,定位Device.exe,看看SimpleDriver.Dll是否被系统加载了.
也可以用Remote Registry Editor的BuildIn 和 Action键来查看


其他:如果把镜像下载到箱子里,可以使用RETAILMSG或者OutputDebugString等把信息输出到串口
 另外到处的SDK安装后EVC不能使用了,因为相应EVC Emulator不能使用,尚待解决。

 

 

SimpleDriver的主要代码
#include <windows.h>
#include <types.h>


static BYTE g_Tmp = 0;      /* 暂存数据变量 */
static DWORD g_OpenCount = 0;    /* 驱动打开计数器 */
 
/*******************************************************************************************
函数名称: DllEntry
描    述: 驱动程序动态库入口
输入参数:  
输出参数:
返    回:
*******************************************************************************************/
BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch ( dwReason )
 {
  case DLL_PROCESS_ATTACH:
   RETAILMSG(1, (TEXT("DRV: DLL_PROCESS_ATTACH./r/n"))); /* 提示动态库加载 */
   DisableThreadLibraryCalls((HMODULE) hInstDll);   
   break;

  case DLL_PROCESS_DETACH:
   RETAILMSG(1, (TEXT("DRV: DLL_PROCESS_DETACH./r/n"))); /* 提示动态库卸载 */
   break;
    }
   
    return (TRUE);
}


/*******************************************************************************************
函数名称: DRV_Init
描    述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置  
输出参数: 无
返    回: 驱动程序句柄
*******************************************************************************************/
DWORD DRV_Init(DWORD dwContext)
{
 RETAILMSG(1, (TEXT("::: DRV_Init./r/n")));  /* 提示驱动加载 */

 g_Tmp = 0;          /* 初始化全局变量的值 */
 g_OpenCount = 0;

 return 1;          /* 返回一个不为零的数表示成功 */
}


/*******************************************************************************************
函数名称: DRV_Deinit
描    述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功
*******************************************************************************************/
BOOL DRV_Deinit(DWORD dwContext)
{
 RETAILMSG(1, (TEXT("::  DRV_Deinit./r/n"))); /* 提示驱动卸载 */
 
 g_Tmp = 0;          /* 恢复全局变量的值 */
 g_OpenCount = 0;

    return TRUE;
}


/*******************************************************************************************
函数名称: DRV_Open
描    述: 打开驱动程序
输入参数: DWORD hDeviceContext: 设备驱动程序引用实例句柄
          DWORD AccessCode    : 访问请求代码,是读和写的组合
          DWORD ShareMode   : 共享模式 
输出参数:
返    回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD DRV_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
 RETAILMSG(1, (TEXT("::: DRV_Open./r/n")));      /* 提示驱动打开 */
 
 // 不允许多个应用程序打开本驱动
 if (g_OpenCount != 0)
 {
  RETAILMSG(1, (TEXT("DRV Open failed./r/n")));/* 提示驱动打开失败 */
  return 0;
 }
 g_OpenCount++;             /* 驱动打开计数器加1 */

    return g_OpenCount;         /* 必须返回一个不为空的句柄 */
}


/*******************************************************************************************
函数名称: DRV_Close
描    述: 驱动程序关闭函数
输入参数: DWORD hOpenContext:驱动程序引用事例句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功
*******************************************************************************************/
BOOL DRV_Close(DWORD hOpenContext)
{
 RETAILMSG(1, (TEXT("::: DRV_Close./r/n")));       /* 提示驱动关闭 */
 
 if (g_OpenCount != 0)
  g_OpenCount--;          /* 驱动打开计数减1 */
  
    return TRUE;
}


/*******************************************************************************************
函数名称: DRV_IOControl
描    述: 驱动程序 I/O 请求
输入参数:
输出参数:
返    回: TRUE: 成功   FALSE: 失败
*******************************************************************************************/
BOOL DRV_IOControl(DWORD hOpenContext,
          DWORD dwCode,
       PBYTE pBufIn,
       DWORD dwLenIn,
       PBYTE pBufOut,
       DWORD dwLenOut,
       PDWORD pdwActualOut)
{
 RETAILMSG(1, (TEXT("::: DRV_IOControl./r/n")));   /* 提示I/O请求函数执行 */
 
 return TRUE;
}


/*******************************************************************************************
函数名称: DRV_Read
描    述: 从本驱动读取数据
输入参数: DWORD hOpenContext: 驱动程序引用事例句柄
          DWORD Count  : 要读的字节数
输出参数: LPVOID pBuffer    : 接收缓冲区
返    回: 实际读到的字节数
*******************************************************************************************/
DWORD DRV_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
 uchar *pReadBuffer;
 
 RETAILMSG(1, (TEXT("::: DRV_Read./r/n")));      /* 提示执行读函数 */
 if ((pBuffer == NULL) || (Count <= 0))
 {                /* 读函数入口参数错误 */
  RETAILMSG(1, (TEXT("::: DRV_Read() parameter is error./r/n")));   
  return 0;
 }
 
 // 映射地址空间
 pReadBuffer = MapPtrToProcess(pBuffer, GetCallerProcess());
 *pReadBuffer = g_Tmp;           /* 返回数据 */
 
 return 1;            /* 返回读取的字节数 */
}


/*******************************************************************************************
函数名称: DRV_Write
描    述: 向本驱动写入数据
输入参数: DWORD hOpenContext: 驱动程序引用事例句柄
          LPVOID pBuffer    : 发送缓冲区
          DWORD Count  : 要写入的字节数
输出参数: 无
返    回: 实际写入的字节数
*******************************************************************************************/
DWORD DRV_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count)
{
 uchar *pWriteBuffer;

 RETAILMSG(1, (TEXT("::: DRV_Write./r/n")));      /* 提示执行写函数 */
 if ((pBuffer == NULL) || (Count <= 0))
 {                /* 写函数入口参数错误 */
  RETAILMSG(1, (TEXT("::: DRV_Write() parameter is error./r/n")));   
  return 0;
 }
 
 // 获取应用程序地址空间数据指针
 pWriteBuffer = MapPtrToProcess((LPVOID)pBuffer, GetCallerProcess());
 g_Tmp = *pWriteBuffer;         /* 保存数据 */

 return 1;
}


/*******************************************************************************************
函数名称: DRV_Seek
描    述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数:
输出参数:
返    回:
*******************************************************************************************/
DWORD DRV_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
 RETAILMSG(1, (TEXT("::: DRV_Seek./r/n")));      /* 提示执行本函数 */

 return 0;
}


/*******************************************************************************************
函数名称: DRV_PowerUp
描    述: 电源上电驱动处理函数
输入参数:
输出参数:
返    回: 无
*******************************************************************************************/
void DRV_PowerUp(void)
{
 RETAILMSG(1, (TEXT("::: DRV_PowerUp./r/n")));    /* 提示执行本函数 */
}


/*******************************************************************************************
函数名称: DRV_PowerDown
描    述: 电源下电驱动处理函数
输入参数:
输出参数:
返    回: 无
*******************************************************************************************/
void DRV_PowerDown(void)
{
 RETAILMSG(1, (TEXT("::: DRV_PowerDown./r/n")));    /* 提示执行本函数 */
}

原创粉丝点击