玩心未泯

卡尔斯希普拉斯

C++博客 首页 新随笔 联系 聚合 管理
  19 Posts :: 0 Stories :: 98 Comments :: 0 Trackbacks
    之前公司由于项目需要让我研究PDA上的WinCE系统下的USB外设驱动开发,刚刚有点入门的感觉结果又终止了这个计划,我也一直在郁闷这个事情,不想现如今,机会又来了。我又开始了驱动开发的研究学习之旅,这里将继续记录我的心得体会。
    之前的入门记录(二)已经讲到了USBDeviceAttach函数,原形这里再列一下:

BOOL USBDeviceAttach(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
                     LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId,
                     LPBOOL fAcceptControl,
                     LPCUSB_DRIVER_SETTINGS lpDriverSettings, DWORD dwUnused);

不过(二)只谈到了它的第一个参数hDevice,调用一句:  LPCUSB_DEVICE lpUsbDev = (lpUsbFuncs->lpGetDeviceInfo)(hDevice); 
就能够获得一个USB_DEVICE的指针,然后顺藤摸瓜可以看到这个设备的许多信息,被命名为Descriptor的,PC上有一个软件叫USBView的可以看到接到USB口上的设备信息,读取的应该就是这个结构。我当时傻乎乎的,自己写打印函数,在驱动程序加载的时候把这些信息MessageBox显示出来:P,所以呢,今天这篇先讨论一下关于这个驱动的调试问题。在MSDN上有关于wince驱动程序调试的专题,大体是介绍使用PB开发驱动的情况下测试、调试驱动程序的,而我是用EVC4开发的,没有那个什么(名字忘记了:P),没法调试。当研究一些驱动的源代码的时候,最开始看到的那些 DEBUGMSG、DEBUGZONE还有个叫什么什么tail的那些宏,其实都是在PB的调试环境下用的, 功能应该是类似TRACE之类的,打印一些信息到Output窗口的,因为没有那个调试环境,所以这些东东都没法用了,因此要看我的驱动加载过程中的一些信息,要么就是打印到文件,要么就是用MessageBox了,我选择用MessageBox直观的显示,呵呵,笨笨的办法还是很好用的,跟设断点似的。
     下面继续说USBDeviceAttach函数,其第二个参数lpUsbFuncs,这个是一个函数指针数组,有点vtable的味道,具体的看看USB_FUNCS这个结构的声明就差不多了,在MSDN中也能够通过这个结构查看其所有指向的函数的调用方法及用途。在驱动程序中,往往要用到这个vtable中的很多函数,所以我们需要把这个vtable保存下来备用,如何保存和备用我会在下篇中写明白,在Attach过程中还需要保存很多有用的东东。
     那么继续往下,lpInterface,一个指向USB_INTERFACE的指针,我一直对这个参数没太弄明白,我在这个函数里面得到的这个指针是一个空指针,而看别人的代码中间,当这个指针为空的时候attach是返回FALSE的,显然对我这种情况是不适用的,我后来想想,觉得大概是因为我的外设Interface的class、subclass、protocol都是0,所以才出现这种情况吧(准确的说是因为我在USBInstallDriver函数中,RegisterClientDriverID调用给的参数USB_DRIVER_SETTINGS结构体中关于Interface的几个变量值我全给的USB_NO_INFO,我后来尝试赋值为0,结果就得到了非空的Interface指针)。那么对于我这种情况,interface是个空指针该怎么办呢?可以用USB_FUNCS中的lpFindInterface来“找出”合适的Interface指针,具体的用法还是看官自己研究MSDN吧。
     其实猛地一下蹦出一个Interface的概念,估计初次接触的都会有点糊涂,我当时也很糊涂,Interface在现如今含义太多了,不过可以肯定这里的不是COM中的Interface~:),在查阅资料的时候,我找到了它的确切定义:
 USB peripheral devices consist of one or more logical components that implement the abilities of the devices. These components are called interfaces.Each interface typically provides some useful grouping of functionality, but exactly what constitutes an interface is an implementation detail. For example, a USB mouse device could present one interface for horizontal and vertical movement information and a separate interface for left and right button information. As another option, the device could present a single interface containing all of the information. Both are valid approaches, but each approach has implications for how the device driver must operate.
这段话我就不翻译了,本来英文就不怎么地,翻译过来有误导之嫌,还是留给大家原汁原味的比较好。
    其实研究wince的驱动,或者单纯的讲USB驱动,还是应该了解一下wince下USB的驱动模型的,貌似很简单的一个模型,但是好像还没有能够找到比较精辟的阐述讲解,看着MSDN能够让你看睡着了也不知所云,只能是边研究边体会,我很想在我的文章里对这个模型进行一番讲解,但是发现自己也没有理解到能够给别人讲解的地步。
    好了,不废话了,继续就Interface这个指针继续往下谈,我看了PB下的USB Printer的驱动源码,在这个阶段它调用了SetInterface这个函数,我也依葫芦画瓢,调用了,但却阻塞在这个调用上不能继续,至今我仍不知道是什么原因。这也可以说是我目前的疑问点之一,文中我用特殊颜色标记出来,有朋友能够解疑释惑的可以和我联系,我自己研究出来了,以后也会在后记中加上其答案。
    其它的似乎就没有太多好说的了,直接在MSDN中间都能够看懂是干什么,今天就先写到这里,下次再写的内容就和我的外设有很直接的关系了,只能是根据我外设的具体情况介绍我探索驱动开发的经历。我的外设还算比较简单的,只有两个BULK的EndPoint,什么是EndPoint?呵呵~~留给看官自己研究下吧~

BTW:经过几天的摸索,我终于完成了我的外设的驱动开发,看着测试程序成功的打开设备,写数据又读数据,心中无比欣慰~~不过由于写程序的时候是摸着石头过河,而且到后来才如愿以偿的看到了PB下USBPrinter的源代码,才发现自己的程序结果实在有点混乱。这两天再调整调整,USBPrinter的源代码中果然还是有不少可以借鉴的东西。

2007.8.6后记:“好”日子差不多又要到头了,这次驱动开发的成果在我看来才只是刚刚可用而已,已经调配我做别的事情了,这方面的研究又要被停止下来了。之后一段时间估计很难抽出时间自己继续深入研究了,回头看看自己写的东西居然没有介绍LPBOOL fAcceptControl这个参数,不过好在介绍这个参数的文章也比较多,简单来说,它是一个输出参数。当把它指向的那个变量赋值为真的时候,我们的设备驱动程序就取得了设备的控制权了,系统也就不会再继续为之寻找匹配的驱动了(我的理解是这样,不知是否有错误)。这里小小的后记补充一下。入门记录(四)可能会在更晚的时候,抽时间纪录下来,希望到时我还记得我要写些什么~:)
posted on 2007-08-01 15:20 SuperPlayeR 阅读(3624) 评论(7)  编辑 收藏 引用 所属分类: WinCE/Mobile应用开发

评论

# re: WinCE下驱动开发入门记录(三) 2007-08-02 09:37 SuperPlayeR
昨晚上睡觉之前顺手把一本买了很久却一直没看的书拿起来翻了翻,linux设备驱动程序,看了看关于usb驱动的章节,发现当初如果刚开始研究的时候就看看这个,可能会少走不少弯路,至少什么是Configuration,什么是Interface,什么是EndPoint它都介绍清楚了~:P
今天如果有时间,我继续写(四),介绍一下。  回复  更多评论
  

# re: WinCE下驱动开发入门记录(三) 2007-08-08 16:08 internetcai
转发了你的文章.........
谢谢你分享经验..


转到www.arm9bbs.com  回复  更多评论
  

# re: WinCE下驱动开发入门记录(三) 2007-08-18 21:48 nonono
期待4......
谢谢!  回复  更多评论
  

# re: WinCE下驱动开发入门记录(三) 2007-08-28 17:23 raul
多谢楼主的分享  回复  更多评论
  

# re: WinCE下驱动开发入门记录(三)[未登录] 2007-11-20 11:15 hh
SetInterface被阻塞的原因是因为你的设备不支持这个函数的实现,一般来说,你不用设置Interface就可以使用USB设备了,SetInterface是在设备有多个接口的情况下,需要设置,但是绝大部分设备都是一个接口,因此不用设置。
  回复  更多评论
  

# re: WinCE下驱动开发入门记录(三)[未登录] 2007-11-30 15:31 Ken
楼上说得没错,还有,CE下面很多类似的函数不必调用的。
对这个SetInterface来说,只需要填充其pipes信息,
指定传输类型等参数,再用lpUsbFuncs里面的open打开pipes
就好。  回复  更多评论
  

# re: WinCE下驱动开发入门记录(三) 2008-09-25 15:45 lannier
我马上也要在手持设备上开发USB驱动,并要实现USB口和RS232之间的转换。刚入门理不清头绪希望大侠给点建议
看了你的文章有点小感悟  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理