Windows CE下的USB设备驱动程序开发实例(二)

301 篇文章 0 订阅
120 篇文章 3 订阅

作者:bjtuzdq

转自:http://blog.csdn.net/bjtuzdq/article/details/3856890


USB鼠标的类的定义如下:

class CMouse

{

public:

CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,

LPCUSB_INTERFACE lpInterface);

~CMouse();

 

BOOL Initialize();

private:

// 传输完毕调用的回调函数

static DWORD CALLBACK MouseTransferCompleteStub(LPVOID lpvNotifyParameter);

// 中断处理函数

static ULONG CALLBACK CMouse::MouseThreadStub(PVOID context);

DWORD MouseTransferComplete();

DWORD MouseThread();

 

BOOL SubmitInterrupt();

BOOL HandleInterrupt();

 

BOOL m_fClosing;

BOOL m_fReadyForMouseEvents;

 

HANDLE m_hEvent;

HANDLE m_hThread;

 

USB_HANDLE m_hDevice;

USB_PIPE m_hInterruptPipe;

USB_TRANSFER m_hInterruptTransfer;

 

LPCUSB_FUNCS m_lpUsbFuncs;

LPCUSB_INTERFACE m_pInterface;

 

BOOL m_fPrevButton1;

BOOL m_fPrevButton2;

BOOL m_fPrevButton3;

 

// 数据接受缓冲区。

BYTE m_pbDataBuffer[8];

};

 

具体实现如下:

 

// 构造函数,初始化时调用

CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,

LPCUSB_INTERFACE lpInterface)

{

m_fClosing = FALSE;

m_fReadyForMouseEvents = FALSE;

m_hEvent = NULL;

m_hThread = NULL;

 

m_hDevice = hDevice;

m_hInterruptPipe = NULL;

m_hInterruptTransfer = NULL;

 

m_lpUsbFuncs = lpUsbFuncs;

m_pInterface = lpInterface;

 

m_fPrevButton1 = FALSE;

m_fPrevButton2 = FALSE;

m_fPrevButton3 = FALSE;

 

memset(m_pbDataBuffer, 0, sizeof(m_pbDataBuffer));

}

 

// 析构函数,用于清除申请的资源。

CMouse::~CMouse()

{

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

m_fClosing = TRUE;

 

// Wake up the connection thread again and give it time to die.

if (m_hEvent != NULL)

{

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

SetEvent(m_hEvent);

 

if (m_hThread != NULL)

{

DWORD dwWaitReturn;

 

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鼠标驱动程序

BOOL CMouse::Initialize()

{

LPCUSB_DEVICE lpDeviceInfo = (*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: EP 0 wrong type (%u)!/r/n"),

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

return FALSE;

}

DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: EP 0:MaxPacket: %u, Interval: %u/r/n"),

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: Error opening interrupt pipe/r/n")));

return (FALSE);

}

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

if (m_hEvent == NULL)

{

RETAILMSG(1,(TEXT("USBMouse: Error on CreateEvent for connect event/r/n")));

return(FALSE);

}

// 创建数据接受线程

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

if (m_hThread == NULL)

{

RETAILMSG(1,(TEXT("USBMouse: Error on CreateThread/r/n")));

return(FALSE);

}

 

return(TRUE);

}

 

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

BOOL CMouse::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: Error in IssueInterruptTransfer/r/n"));

return FALSE;

}

else

{

DEBUGMSG(ZONE_TRANSFER,(L"USBMouse::SubmitInterrupt,Transfer:0x%X/r/n",

m_hInterruptTransfer));

}

return TRUE;

}

 

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

BOOL CMouse::HandleInterrupt()

{

DWORD dwError;

DWORD dwBytes;

 

DWORD dwFlags = 0;

INT dx = (signed char)m_pbDataBuffer[1];

INT dy = (signed char)m_pbDataBuffer[2];

 

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

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

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

 

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

{

DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error in GetTransferStatus(0x%X)/r/n"),

m_hInterruptTransfer));

return FALSE;

}

else

{

DEBUGMSG(ZONE_TRANSFER,(TEXT("USBMouse::HandleInterrupt, hTransfer 0x%X complete (%u bytes, Error:%X)/r/n"),

m_hInterruptTransfer,dwBytes,dwError));

}

 

if (!SubmitInterrupt())

return FALSE;

 

if(dwError != USB_NO_ERROR)

{

DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error 0x%X in interrupt transfer/r/n"),dwError));

return TRUE;

}

 

if(dwBytes < 3)

{

DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Invalid byte cnt %u from interrupt transfer/r/n"),dwBytes));

return TRUE;

}

 

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("USBMouse event: dx:%d, dy:%d, dwFlags:0x%X (B1:%u, B2:%u, B3:%u)/r/n"),

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

 

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

if (m_fReadyForMouseEvents)

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

else

m_fReadyForMouseEvents = IsAPIReady(SH_WMGR);

 

return TRUE;

}

 

 

DWORD CALLBACK CMouse::MouseTransferCompleteStub(LPVOID lpvNotifyParameter)

{

CMouse * pMouse = (CMouse *)lpvNotifyParameter;

return(pMouse->MouseTransferComplete());

}

 

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

DWORD CMouse::MouseTransferComplete()

{

if (m_hEvent)

SetEvent(m_hEvent);

return 0;

}

 

 

ULONG CALLBACK CMouse::MouseThreadStub(PVOID context)

{

CMouse * pMouse = (CMouse *)context;

return(pMouse->MouseThread());

}

 

// USB鼠标线程

DWORD CMouse::MouseThread()

{

DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: Worker thread started/r/n")));

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: Event signalled, but transfer not complete/r/n")));

// The only time this should happen is if we get an error on the transfer

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

break;

}

}

}

RETAILMSG(1,(TEXT("USBMouse: Worker thread exiting/r/n")));

return(0);

}

 

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

 

微软的Windows CE的Platform Build中已经带有USB Printer和USB Mass Storage Disk的驱动的源代码了,好好研究一下,你一定回受益非浅的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows CE操作系统是微软针对嵌入式领域开发的一个全新的操作系统,具备抢占式多任务功能以及强大的通信能力,广泛应用在信息设备、移动设备、电子产品以及嵌入式应用等非PC领域。随着计算机技术、网络技术和多媒体通信技术的发展,以及PDA、信息家电、机顶盒等为代表的嵌入式系统应用的广泛发展,嵌入式系统已经越来越走近普通人的生活,随之而来的,就是对嵌入式软、硬件设计的广泛需要。 本课题所涉及的研究方向是探索在Windows CE 5.0嵌入式操作系统下进行USB总线设备驱动程序开发相关原理。USB总线已经成为微机与功能繁多的外部设备连接的重要标准手段,所以以Windows CE 5.0为操作系统的嵌入式产品具备对USB总线的支持将能连接更多的具有USB总线接口形式的功能设备,扩大产品的应用领域,成为该产品的一个突出竞争优势。因此本课题的研究内容具有很大的理论意义以及实际应用价值。 在研究过程中,由于在嵌入式系统下开发USB总线驱动的相关成果资料较少,本课题横向类比了相关领域如Windows,Linux系统下USB总线设备驱动程序开发的各类成熟和较成熟思想,结合Windows CE操作系统下开发相关的各种中英文资料,并分析该操作系统自带的各种驱动源代码示例,从而提出以流驱动模式为策略的框架下具体开发该类总线设备驱动程序的流程。 分析Windows CE操作系统对于USB总线的支持,并结合在ARMSYS2410嵌入式开发板上关于Webeye 2000的USB摄像头的开发步骤,详细阐述了WindowsCEUSB摄像头驱动程序开发的策略,并根据该策略开发USB总线实验设备驱动程序,这是本课题的主体部分。由于针对的应用领域不同,相对于成熟的如Windows,Linux等大型操作系统,Windows CE嵌入式系统中设备驱动程序开发机制较为精简,可以根据不同的功能设备灵活的实现者的通信。本文所总结的驱动开发策略是流驱动的形式,可以运用于产生流式数据的设备或者与这种方式相关相近的设备驱动程序开发中。
大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值