如何开发一个WinCE 6的流设备驱动

来源:互联网 发布:局域网通话软件 编辑:程序博客网 时间:2024/05/17 03:29

•在BSP的Drivers目录下,创建新驱动程序的目录,比如MyDriver
•修改dirs文件,在变量DIRS中增加新目录MyDriver
•创建文件Sources,内容如下:
view plaincopy to clipboardprint?
01.TARGETNAME=MyDriver  
02.RELEASETYPE=PLATFORM  
03.TARGETTYPE=DYNLINK   
04.DEFFILE=MyDriver.def  
05.DLLENTRY=DllEntry  
06.TARGETLIBS= $(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib  
07. 
08.SOURCES=MyDriver.c 
TARGETNAME=MyDriver
RELEASETYPE=PLATFORM
TARGETTYPE=DYNLINK
DEFFILE=MyDriver.def
DLLENTRY=DllEntry
TARGETLIBS= $(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib

SOURCES=MyDriver.c
 

•创建文件Makefile.inc,内容如下:
view plaincopy to clipboardprint?
01.# 
02.# DO NOT EDIT THIS FILE!!! Edit ./sources. if you want to add a new source 
03.# file to this component. This file merely indirects to the real make file 
04.# that is shared by all the components of Windows CE. 
05.#  
06.!INCLUDE $(_MAKEENVROOT)/makefile.def 
#
# DO NOT EDIT THIS FILE!!! Edit ./sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of Windows CE.
#
!INCLUDE $(_MAKEENVROOT)/makefile.def
 

•创建文件MyDriver.def,内容如下:
view plaincopy to clipboardprint?
01.LIBRARY         MyDriver  
02. 
03.EXPORTS         XXX_Init  
04.                XXX_Deinit  
05.                XXX_Open  
06.                XXX_Close  
07.                XXX_Read  
08.                XXX_Write  
09.                XXX_Seek  
10.                XXX_PowerDown  
11.                XXX_PowerUp  
12.                XXX_IOControl 
LIBRARY         MyDriver

EXPORTS         XXX_Init
                XXX_Deinit
                XXX_Open
                XXX_Close
                XXX_Read
                XXX_Write
                XXX_Seek
                XXX_PowerDown
                XXX_PowerUp
                XXX_IOControl
 

•创建文件MyDriver.c,内容如下:
 
view plaincopy to clipboardprint?
01.#include <windows.h> 
02.#include <Devload.h>  
03. 
04. 
05.BOOL XXX_Deinit(DWORD hDeviceContext)  
06.{  
07.    return TRUE;  
08.}  
09. 
10.DWORD XXX_Init(ULONG RegistryPath)  
11.{  
12.    HKEY    hKey;  
13. 
14.    RETAILMSG(1, (TEXT("XXX_Init/n")));  
15.    hKey = OpenDeviceKey((LPCTSTR) RegistryPath);  
16.    if(!hKey)  
17.    {  
18.        RETAILMSG(1, (TEXT("Failed to open devkeypath,/r/n")));  
19.    }  
20.    else 
21.    {  
22.        /* Read values from registry if needed */ 
23.        RegCloseKey(hKey);  
24.    }  
25. 
26.    return TRUE;  
27.}  
28. 
29. 
30.BOOL WINAPI DllEntry(HINSTANCE DllInstance, ULONG Reason, LPVOID Reserved)  
31.{  
32.    RETAILMSG(1, (TEXT("MyDriver: DllEntry/n")));  
33.    return TRUE;  
34.}  
35. 
36. 
37.VOID XXX_PowerUp(DWORD hDeviceContext)  
38.{  
39.}  
40. 
41. 
42.VOID XXX_PowerDown(DWORD hDeviceContext)  
43.{  
44.}  
45. 
46. 
47.DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)  
48.{  
49.    return hDeviceContext;  
50.}  
51. 
52. 
53.BOOL XXX_Close(DWORD hOpenContext)  
54.{  
55.    return TRUE;  
56.}  
57. 
58. 
59.DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)  
60.{  
61.    return 0;  
62.}  
63. 
64. 
65.DWORD XXX_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)  
66.{  
67.    return 0;  
68.}  
69. 
70. 
71.DWORD XXX_Seek(DWORD hOpenContext, long Amount, DWORD Type)  
72.{  
73.    return 0;  
74.}  
75. 
76. 
77.BOOL XXX_IOControl  
78.(  
79.    DWORD   hOpenContext,  
80.    DWORD   dwCode,  
81.    PBYTE   pBufIn,  
82.    DWORD   dwLenIn,  
83.    PBYTE   pBufOut,  
84.    DWORD   dwLenOut,  
85.    PDWORD  pdwActualOut  
86.)  
87.{  
88.    BOOL    RetVal = TRUE;  
89. 
90.    switch(dwCode)  
91.    {  
92.    default:    RetVal = FALSE; break;  
93.    }  
94. 
95.    return RetVal;  
96.} 
#include <windows.h>
#include <Devload.h>


BOOL XXX_Deinit(DWORD hDeviceContext)
{
 return TRUE;
}

DWORD XXX_Init(ULONG RegistryPath)
{
 HKEY hKey;

 RETAILMSG(1, (TEXT("XXX_Init/n")));
 hKey = OpenDeviceKey((LPCTSTR) RegistryPath);
 if(!hKey)
 {
  RETAILMSG(1, (TEXT("Failed to open devkeypath,/r/n")));
 }
 else
 {
  /* Read values from registry if needed */
  RegCloseKey(hKey);
 }

 return TRUE;
}


BOOL WINAPI DllEntry(HINSTANCE DllInstance, ULONG Reason, LPVOID Reserved)
{
 RETAILMSG(1, (TEXT("MyDriver: DllEntry/n")));
 return TRUE;
}


VOID XXX_PowerUp(DWORD hDeviceContext)
{
}


VOID XXX_PowerDown(DWORD hDeviceContext)
{
}


DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
 return hDeviceContext;
}


BOOL XXX_Close(DWORD hOpenContext)
{
 return TRUE;
}


DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
 return 0;
}


DWORD XXX_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
 return 0;
}


DWORD XXX_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
 return 0;
}


BOOL XXX_IOControl
(
 DWORD hOpenContext,
 DWORD dwCode,
 PBYTE pBufIn,
 DWORD dwLenIn,
 PBYTE pBufOut,
 DWORD dwLenOut,
 PDWORD pdwActualOut
)
{
 BOOL RetVal = TRUE;

 switch(dwCode)
 {
 default: RetVal = FALSE; break;
 }

 return RetVal;
}
 

•在platform.bib或者project.bib中,加入此驱动:
view plaincopy to clipboardprint?
01.MyDriver.dll $(_FLATRELEASEDIR)/MyDriver.dll  NK  K 
MyDriver.dll $(_FLATRELEASEDIR)/MyDriver.dll  NK  K

•在platform.reg或者project.reg中,设置此驱动为BuildIn类型,自动加载:
view plaincopy to clipboardprint?
01.[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/MyDriver]  
02.    "Dll"="MyDriver.dll" 
03.    "Order"=dword:4  
04.    "Prefix"="XXX" 
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/MyDriver]
    "Dll"="MyDriver.dll"
    "Order"=dword:4
    "Prefix"="XXX"

至此,一个没有实现任何功能的驱动完成了,下面描述如何在驱动中使用中断。

•创建中断线程函数(IST),在线程中申请并等待中断:
view plaincopy to clipboardprint?
01.static DWORD WINAPI MyInterruptThread(LPVOID p)  
02.{  
03.    DWORD   RetVal = 0;  
04.    HANDLE  hEvent;  
05.    DWORD   SysintrValue;  
06.    DWORD   IRQ = MYDRIVER_IRQ;  
07. 
08.    /* Create an Event */ 
09.    hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
10. 
11.    /* Register with the Kernel */ 
12.    KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(DWORD), &SysintrValue, sizeof(DWORD), NULL);  
13.    RetVal = InterruptInitialize(SysintrValue, hEvent, NULL, 0);  
14. 
15.    /* Set the Thread Priority */ 
16.    CeSetThreadPriority(GetCurrentThread(), 150);  
17. 
18.    while(1)  
19.    {  
20.        /* Wait for the Event to be Signaled */ 
21.        RetVal = WaitForSingleObject(hEvent, 2000);  
22. 
23.        if(RetVal == WAIT_OBJECT_0)  
24.        {  
25.            /* 
26.             * Service the Interrupt  
27.             * In this case suspend the device 
28.             */ 
29.            SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);  
30. 
31.            /* Tell the Kernel that the Interrupt has been Serviced */ 
32.            InterruptDone(SysintrValue);  
33.        }  
34.        else if(RetVal == WAIT_TIMEOUT)  
35.        {  
36.            /* 
37.             * Optional, provide a way to stop the thread when the driver unloads  
38.             * This is optional because the driver may never unload 
39.             */ 
40.            if(StopThreads) break;  
41.        }  
42.    }  
43. 
44.    /* When and if the driver unloads and the thread exits release resources */ 
45.    InterruptDisable(SysintrValue);  
46.    CloseHandle(hEvent);  
47.    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &SysintrValue, sizeof(DWORD), NULL, 0, NULL);  
48. 
49.    return 0;  
50.} 
static DWORD WINAPI MyInterruptThread(LPVOID p)
{
 DWORD RetVal = 0;
 HANDLE hEvent;
 DWORD SysintrValue;
 DWORD IRQ = MYDRIVER_IRQ;

 /* Create an Event */
 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

 /* Register with the Kernel */
 KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(DWORD), &SysintrValue, sizeof(DWORD), NULL);
 RetVal = InterruptInitialize(SysintrValue, hEvent, NULL, 0);

 /* Set the Thread Priority */
 CeSetThreadPriority(GetCurrentThread(), 150);

 while(1)
 {
  /* Wait for the Event to be Signaled */
  RetVal = WaitForSingleObject(hEvent, 2000);

  if(RetVal == WAIT_OBJECT_0)
  {
   /*
    * Service the Interrupt
    * In this case suspend the device
    */
   SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);

   /* Tell the Kernel that the Interrupt has been Serviced */
   InterruptDone(SysintrValue);
  }
  else if(RetVal == WAIT_TIMEOUT)
  {
   /*
    * Optional, provide a way to stop the thread when the driver unloads
    * This is optional because the driver may never unload
    */
   if(StopThreads) break;
  }
 }

 /* When and if the driver unloads and the thread exits release resources */
 InterruptDisable(SysintrValue);
 CloseHandle(hEvent);
 KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &SysintrValue, sizeof(DWORD), NULL, 0, NULL);

 return 0;
}


 

•驱动Dll被加载后,系统首先调用DllEntry,随后调用XXX_Init。修改XXX_Init,加入线程启动代码:
view plaincopy to clipboardprint?
01.HANDLE hthrd;  
02.      
03.// Start thread  
04.hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MyInterruptThread,NULL,0,NULL);  
05.// Since we don't need the handle, close it now.  
06.CloseHandle(hthrd); 
HANDLE hthrd;
 
// Start thread
hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MyInterruptThread,NULL,0,NULL);
// Since we don't need the handle, close it now.
CloseHandle(hthrd);

如果驱动只需要处理一个中断,WaitForSingleObject可以处理得很好,如果有多个中断需要处理时,能依葫芦画瓢,创建多个event,每个event注册一个中断,然后使用WaitForMultipleObjects吗?很遗憾,虽然WinCE支持WaitForMultipleObjects,但对于注册到中断的event,只允许等待一个,考虑到中断处理程序所要求的高性能,为了避免进入死锁,当event数目大于1时,WaitForMultipleObjects将会失败,GetLastError返回参数无效的错误代码(是的,如果只有一个event,WaitForMultipleObjects仍然会成功)。

在这种情况下,一种解决方法是,创建多个IST,每个IST处理一个中断。

此外,还有另一种更好的方法,就是把同一个event注册到多个中断,然后使用WaitForSingleObject等待此event,每个中断被触发时,event都会获得信号:

view plaincopy to clipboardprint?
int i;  
HANDLE hEvent;  
 
// Create an Event  
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
      
// Init all interrupt to a event  
for(i=0; i<MY_INT_COUNT; i++)  
{  
    // Register with the Kernel  
    KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irqs[i], sizeof(DWORD), &intrs[i], sizeof(DWORD), NULL) ;  
    InterruptInitialize( intrs[i], hEvent, NULL, 0 );  
}  
 
.  
.  
.  
.  
 
 
 
// When and if the driver unloads and the thread exits release resources  
for(i=0;i<MY_INT_COUNT;i++)  
{  
    InterruptDisable( intrs[i]);      
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &intrs[i], sizeof(DWORD), NULL, 0, NULL);  
}  
 
CloseHandle( hEvent ); 
int i;
HANDLE hEvent;

// Create an Event
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
 
// Init all interrupt to a event
for(i=0; i<MY_INT_COUNT; i++)
{
 // Register with the Kernel
 KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irqs[i], sizeof(DWORD), &intrs[i], sizeof(DWORD), NULL) ;
 InterruptInitialize( intrs[i], hEvent, NULL, 0 );
}

.
.
.
.

 

// When and if the driver unloads and the thread exits release resources
for(i=0;i<MY_INT_COUNT;i++)
{
 InterruptDisable( intrs[i]); 
 KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &intrs[i], sizeof(DWORD), NULL, 0, NULL);
}

CloseHandle( hEvent );

(参考了Bruce Eitman的文章,http://geekswithblogs.net/BruceEitman/Default.aspx)

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/noodies/archive/2009/06/26/4299694.aspx

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 市场监督管理局罚款怎么办 东莞居住证掉了怎么办 工商注销了税务怎么办 楼道自来水爆了怎么办 工商证没年检怎么办 工行信用卡被锁怎么办 外地卡密码锁了怎么办 营业执照年审过期了怎么办 工商营业执照吊销了怎么办 小规模企业工商年检怎么办 血流变检查偏高怎么办 信誉卡没有邮箱怎么办 税务年报没报怎么办 工商忘记年审了怎么办 营业执照脱审了怎么办 公司年审没有弄怎么办 车检标志丢了怎么办 机动车年检丢了怎么办 汽车保险标志丢了怎么办 车辆年检贴丢失怎么办 车检标贴丢了怎么办 检验标贴丢了怎么办 小车换年检标志怎么办 职称证忘记审验怎么办 联合年报没报怎么办 职称年审过期了怎么办 嘉兴驾模预约怎么办 电大考试去不了怎么办 负债高怎么办房贷 宁波鄞州银行卡怎么办 硕士学位实验数据不好怎么办 小区外过车很吵怎么办 建筑物初级消防证书怎么办 毕业答辩去不了怎么办 卡波西水痘样疹怎么办 58企业认证失败怎么办 炸鸡店没生意怎么办 你好漂亮重名了怎么办 医保卡被冒用怎么办 理财钱被骗走怎么办 个体户怎么办三方协议