您当前的位置:五五电子网电子知识电子学习基础知识电脑-单片机-自动控制如何编写Windows CE.net的usb驱动程序 正文
如何编写Windows CE.net的usb驱动程序

如何编写Windows CE.net的usb驱动程序

点击数:7529 次   录入时间:03-04 11:54:00   整理:http://www.55dianzi.com   电脑-单片机-自动控制

  CMouse::~CMouse()

  {

  //通知系统去关闭相关的函数接口。

  m_fClosing=TRUE;

  //Wakeuptheconnectionthreadagainandgiveittimetodie.

  if(m_hEvent!=NULL)

  {

  //通知关闭数据接受线程。

  SetEvent(m_hEvent);

  if(m_hThread!=NULL)

  {

  DWORDdwWaitReturn;

  dwWaitReturn=WaitForSingleObject(m_hThread,1000);

  if(dwWaitReturn!=WAIT_OBJECT_0)

  {

  TerminateThread(m_hThread,DWORD(-1));

  }

  CloseHandle(m_hThread);

  m_hThread=NULL;

  }

  CloseHandle(m_hEvent);

  m_hEvent=NULL;

  }

  if(m_hInterruptTransfer)

  (*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);

  if(m_hInterruptPipe)

  (*m_lpUsbFuncs->lpClosePipe)(m_hInterruptPipe);

  }

  //初始化USB鼠标驱动程序

  BOOLCMouse::Initialize()

  {

  LPCUSB_DEVICElpDeviceInfo=(*m_lpUsbFuncs->lpGetDeviceInfo)(m_hDevice);

  //检测配置:USB鼠标应该只有一个中断管道

  if((m_pInterface->lpEndpoints[0].Descriptor.bmAttributes&USB_ENDPOINT_TYPE_MASK)!=USB_ENDPOINT_TYPE_INTERRUPT)

  {

  RETAILMSG(1,(TEXT("!USBMouse:EP0wrongtype(%u)!rn"),

  m_pInterface->lpEndpoints[0].Descriptor.bmAttributes));

  returnFALSE;

  }

  DEBUGMSG(ZONE_INIT,(TEXT("USBMouse:EP0:MaxPACket:%u,Interval:%urn"),

  m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,

  m_pInterface->lpEndpoints[0].Descriptor.bInterval));

  m_hInterruptPipe=(*m_lpUsbFuncs->lpOpenPipe)(m_hDevice,

  &m_pInterface->lpEndpoints[0].Descriptor);

  if(m_hInterruptPipe==NULL){

  RETAILMSG(1,(TEXT("Mouse:Erroropeninginterruptpipern")));

  return(FALSE);

  }

  m_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);

  if(m_hEvent==NULL)

  {

  RETAILMSG(1,(TEXT("USBMouse:ErroronCreateEventforconnecteventrn")));

  return(FALSE);

  }

  //创建数据接受线程

  m_hThread=CreateThread(0,0,MouseThreadStub,this,0,NULL);

  if(m_hThread==NULL)

  {

  RETAILMSG(1,(TEXT("USBMouse:ErroronCreateThreadrn")));

  return(FALSE);

  }

  return(TRUE);

  }

  //从USB鼠标设备中读出数据,产生相应的鼠标事件。

  BOOLCMouse::SubmitInterrupt()

  {

  if(m_hInterruptTransfer)

  (*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);

  //从USB鼠标PIPE中读数据

  m_hInterruptTransfer=(*m_lpUsbFuncs->lpIssueInterruptTransfer)

  (m_hInterruptPipe,MouseTransferCompleteStub,this,

  USB_IN_TRANSFER|USB_SHORT_TRANSFER_OK,//表示读数据

  min(m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,

  sizeof(m_pbDataBuffer)),

  m_pbDataBuffer,

  NULL);

  if(m_hInterruptTransfer==NULL)

  {

  DEBUGMSG(ZONE_ERROR,(L"!USBMouse:ErrorinIssueInterruptTransferrn"));

  returnFALSE;

  }

  else

  {

  DEBUGMSG(ZONE_TRANSFER,(L"USBMouse::SubmitInterrupt,Transfer:0x%Xrn",

  m_hInterruptTransfer));

  }

  returnTRUE;

  }

  //处理鼠标中断传输的数据

  BOOLCMouse::HandleInterrupt()

  {

  DWORDdwError;

  DWORDdwBytes;

  DWORDdwFlags=0;

  INTdx=(signedchar)m_pbDataBuffer[1];

  INTdy=(signedchar)m_pbDataBuffer[2];

  BOOLfButton1=m_pbDataBuffer[0]&0x01?TRUE:FALSE;

  BOOLfButton2=m_pbDataBuffer[0]&0x02?TRUE:FALSE;

  BOOLfButton3=m_pbDataBuffer[0]&0x04?TRUE:FALSE;

  if(!(*m_lpUsbFuncs->lpGetTransferStatus)(m_hInterruptTransfer,&dwBytes,&dwError))

  {

  DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse:ErrorinGetTransferStatus(0x%X)rn"),

  m_hInterruptTransfer));

  returnFALSE;

  }

  else

  {

  DEBUGMSG(ZONE_TRANSFER,(TEXT("USBMouse::HandleInterrupt,hTransfer0x%Xcomplete(%ubytes,Error:%X)rn"),

  m_hInterruptTransfer,dwBytes,dwError));

  }

  if(!SubmitInterrupt())

  returnFALSE;

  if(dwError!=USB_NO_ERROR)

  {

  DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse:Error0x%Xininterrupttransferrn"),dwError));

  returnTRUE;

  }

  if(dwBytes<3)

  {

  DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse:Invalidbytecnt%ufrominterrupttransferrn"),dwBytes));

  returnTRUE;

  }

  if(dx||dy)

  dwFlags|=MOUSEEVENTF_MOVE;

  if(fButton1!=m_fPrevButton1)

  {

  if(fButton1)

  dwFlags|=MOUSEEVENTF_LEFTDOWN;

  else

  dwFlags|=MOUSEEVENTF_LEFTUP;

  }

  if(fButton2!=m_fPrevButton2)

  {

  if(fButton2)

  dwFlags|=MOUSEEVENTF_RIGHTDOWN;

  else

  dwFlags|=MOUSEEVENTF_RIGHTUP;

  }

  if(fButton3!=m_fPrevButton3)

  {

  if(fButton3)

  dwFlags|=MOUSEEVENTF_MIDDLEDOWN;

  else

  dwFlags|=MOUSEEVENTF_MIDDLEUP;

  }

  m_fPrevButton1=fButton1;

  m_fPrevButton2=fButton2;

  m_fPrevButton3=fButton3;

  DEBUGMSG(ZONE_EVENTS,

  (TEXT("USBMouseevent:dx:%d,dy:%d,dwFlags:0x%X(B1:%u,B2:%u,B3:%u)rn"),

  dx,dy,dwFlags,fButton1,fButton2,fButton3));

  //通知系统产生鼠标事件

  if(m_fReadyForMouseEvents)

  mouse_event(dwFlags,dx,dy,0,0);

  else

  m_fReadyForMouseEvents=ISAPIReady(SH_WMGR);

  returnTRUE;

  }

  DWORDCALLBACKCMouse::MouseTransferCompleteStub(LPVOIDlpvNotifyParameter)

  {

  CMouse*pMouse=(CMouse*)lpvNotifyParameter;

  return(pMouse->MouseTransferComplete());

  }

  //数据传输完毕回调函数

  DWORDCMouse::MouseTransferComplete()

  {

  if(m_hEvent)

  SetEvent(m_hEvent);

  return0;

  }

  ULONGCALLBACKCMouse::MouseThreadStub(PVOIDcontext)

  {

  CMouse*pMouse=(CMouse*)context;

  return(pMouse->MouseThread());

  }

  //USB鼠标线程

  DWORDCMouse::MouseThread()

  {

  DEBUGMSG(ZONE_INIT,(TEXT("USBMouse:Workerthreadstartedrn")));

  SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);

  if(SubmitInterrupt())

  {

  while(!m_fClosing)

  {

  WaitForSingleObject(m_hEvent,INFINITE);

  if(m_fClosing)

  break;

  if((*m_lpUsbFuncs->lpIsTransferComplete)(m_hInterruptTransfer))

  {

  if(!HandleInterrupt())

  break;

  }

  else

  {

  RETAILMSG(1,(TEXT("!USBMouse:Eventsignalled,buttransfernotcompletern")));

  //Theonlytimethisshouldhappenisifwegetanerroronthetransfer

  ASSERT(m_fClosing||(m_hInterruptTransfer==NULL));

  break;

  }

  }

  }

  RETAILMSG(1,(TEXT("USBMouse:Workerthreadexitingrn")));

  return(0);

  }

  看到了没有,其实USB的驱动程序编写就这么简单,类似的其他设备,例如打印机设备,就有BulkOUTPIPE,需要Bulk传输,那就需要了解一下IssueBulkTransfer()的应用。当然如果是开发USBMassStorageDisk的驱动,那就需要了解更多的协议,例如Bulk-OnlyTransport协议等。

  微软的WindowsCE.NET的PlatformBuild中已经带有USBPrinter和USBMassStorageDisk的驱动的源代码了,好好研究一下,你一定回受益非浅的。



上一页  [1] [2] [3] 


本文关键字:如何  程序  Windows  电脑-单片机-自动控制电子学习 - 基础知识 - 电脑-单片机-自动控制