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

•在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值