【原创】关于wince os开发面试的总结系列之驱动

今天对于驱动方面在面试中遇到的问题进行一个简单的总结,也是一些基本的知识但是会常常用到,所以还是需要引起注意,时常要看看。另外一个就是在驱动中所牵涉到的一些其他的话题,比如非常重要的一个就是电源管理了,电源管理最近也在研究但一直没有实际操作开发过,HJB最近的一篇博文中也简单介绍了一下电源管理方面的知识,这里也摆出来,在面试的时候当然笔试就没办法了,面试的时候会提出来,至少我是遇到过。当然还有例如显示驱动之类的比较复杂的驱动,这些在面试专门的开发岗位的时候可能会细问,这里由于篇幅有限,我们只对一些基础通讯类驱动问题进行一个总结和提出,另外对电源管理在这里多说一些。

-------------------------------------------------------------------------------------------

Q1:驱动程序是干嘛用的?
A1:驱动程序是一个抽象物理设备或者虚拟设备的功能软件,驱动程序管理这些设备的操作;

Q2:驱动程序有哪些种类?
A2:一般来分有内建驱动和可安装驱动,分层和不分层驱动以及本地和流式驱动这几种分类;(这里的分层和不分层的驱动就是MDD和PDD昨天的文章中已经对这个概念进行描述了,这里就不多说,请大家参考上一篇文章中的内容)

Q3:本地驱动和流失驱动各有什么特点,如何分类?
A3:本地驱动由于它们会使用wince中特定的接口,所以这些设备的接口是特殊定制的,微软也对每一个本地设备有特别的规定,所以类似于在本地建立一个驱动,所以称为本地驱动,很常见的例子比如说显示驱动就是一个本地驱动,在PB中提供参考实例中,本地驱动的实例有:显示驱动,键盘驱动,触摸板驱动,指示LED驱动。从这些驱动不难看出,都是在系统中会一直处于运行状态,从系统开始工作到掉电或者复位都是会处于持续工作状态。
关于流式驱动也是相对于本地驱动来说的,流式驱动通常有固定的流接口,其通常与文件系统的API配合使用,这些驱动都有固定的接口与应用层程序链接,也就是一些固定的文件API函数例如READFILE,WRITEFIEL,CREATEFILE,DEVICEIOCONTROL这些个函数。

Q4:简单描述下驱动的开发过程,自己编写的驱动是如何加载到wince系统当中的?
A4:首先我们对开发对象的硬件特性分析,分析完成后我们需要做的是在对于BSP包下的DRIVER目录下为我们的驱动建立一个目录,并在DRIVER文件目录下的DIR中将其包含,接着我们就可以在我们新建的驱动目录下进行程序代码的开发编写,其中包括驱动程序,source文件,以及makefile文件,驱动程序由开发对象所决定,source文件决定了驱动生成的dll库的名称,驱动程序中所需要引用到库的名称,所包含源程序文件的名称,以及一些编译条件,例如生成文件类型,DLL函数入口等,做完以上的工作可以尝试对这个目录进行build,如果无程序错误将会生成一个dll文件,这时我们就可以在platform.reg和platform.bib文件中对这个驱动进行加载,reg文件中主要是描述驱动的特征,如是流驱动则一般建立在buildin注册表路径下,同时指名所调用的dll库名称,以及其自身的名称缩写以及索引等信息,如需要对此驱动进行电源管理,还需要加入ICLASS键值,在bib文件中则需要在FILE段将其dll的文件路径加入,以使的在编译生成image时加入此dll,到这里一个驱动的基本开发就基本完成了。当系统启动时,系统会自动加载其镜像中包含的设备,对于流驱动来说,当系统启动以后,首先会去执行XXX_init文件,将设备加载到系统中,用户可以通过createfile来将设备打开,此时设备将会执行XXX_open将设备打开,当关闭设备时,驱动会执行XXX_close,将设备关闭,同时,需要考虑电源管理时,XXX_POWERUP和XXX_POWERDOWN是两个比较重要的接口,当系统从挂起状态到恢复正常状态时,系统会去执行XXX_POWERUP,而系统进入挂起状态时,XXX_PWERDOWN会被执行,在这两个函数中可以对设备进行电源的开启和关闭,以控制电源,进行电源管理;

Q5:什么是DMA?
A5:DMA是直接内存访问的缩写,在没有CPU的帮助下,数据从设备移动到内存或者从内存移动到设备的一种方法,DMA可以有两种方式实现,第一是使用CEDDK函数,另一种是使用内核函数,一般推荐是使用CEDDK来操作。

Q6:简单描述下一个驱动的电源管理是如何开发实现的?
A6:1.首先在定制系统是加入电源管理的组件,通常只要在Catalog中添加就可以;2.主要是在现有的驱动上添加电源管理的功能。对于流式驱动来说,就是在DeviceIoControl部分添加电源管理的相关消息处理部分,也就是说流驱动主要是在XXX_IOControl中,实现IOCTL_POWER_CAPABILITIES、IOCTL_POWER_QUERY、 IOCTL_POWER_SET和IOCTL_POWER_GET。而内建驱动,例如显示驱动,就需要直接去调用AdvertiseInterface函数。另外,对于流式驱动来说,上面的问题也提到了需要添加一个ICLASS来声明本设备需要电源管理。3.通过应用层函数实现对设备的电源管理和控制,主要就是在应用程序中通过调用电源管理的API,协助系统管理各个设备和整个系统的工作状态。

进一步的参考请查看HJB-we blog http://www.cnblogs.com/we-hjb/archive/2010/01/27/1657973.html

Q7:简单描述下I2C协议
Q7:I2C协议是由飞利浦公司开发的一种2线协议,I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
I2C分读写两种操作,读操作有三种基本操作:当前地址读、随机读和顺序读。应当注意的是:最后一个读操作的第9个时钟周期不是“不关心”。为了结束读操作,主机必须在第9个周期间发出停止条件或者在第9个时钟周期内保持SDA为高电平、然后发出停止条件。写操作分为字节写和页面写两种操作,对于页面写根据芯片的一次装载的字节不同有所不同。

以上是一些通用的问题,都是有还算比较标准的答案,下面的问题可能需要大家自己考虑下了,有的是因为答案很多,要针对不同的平台来说,有的是太复杂了,基本上说完天都黑了那种的,大家可以自己去考虑下组织下语言来应对,这里就不给出来A了,因为有些我自己都还不是很清楚如何去作答才算让考官满意的,总之有一次面试考官足足面试了1个多小时,wince从驱动到AP所有能问的我感觉都被问到了,实在是傻了,发现自己实在是井底之蛙,还需要继续努力学习;

Q8:DircetDraw是什么?
PS.当时考官直接问的是,DircetDraw用过没?说说看。大家自己找找答案,可以说很久这个问题。

Q9:描述下系统唤醒休眠的过程,系统是如何操作的?
PS.这个问题一般会结合你所操作过的平台来说,但一般都差不多,有一个GPIO产生中断之类的信号,系统响应到了以后去执行一系列的休眠动作,比如说关闭一些电源,操作流驱动中的powerdown关闭设备,执行一些汇编的指令关闭时钟,保留32.768KHZ时钟,内存如何控制,Flash如何控制,这些按照你实际平台的情况说一遍就可以了。

Q10:描述一个你开发过的IC驱动,描述下那个IC的特性。
PS.实话实说就可以了

Q11:两个驱动之间,如果想传递数据,一般你会怎么去处理?
PS.我处理的方式是通过一个AP程序将两个驱动联系起来,通过一个进程互斥机制来控制两个设备之间数据的传递,也就是通过AP申请一个内存空间,两个设备对数据进行互斥共享,AP负责控制两个设备获取数据的条件,控制设备读取和写入,这个其实我是实际操作过两个IC做驱动后互相通讯传递数据,中间还用到了一个中断来控制数据的读写,采用一个中断的话数据也就不会出现死等或者独占不出来的情况,一方发出数据到内存给出中断,另一方接到中断后去读内存,这样来互斥。大家也可以考虑下有其他的方法,我这个方法需要有一个硬件的中断,对硬件有要求;

Q12:MLC是什么?
PS.我一开始真不知道MLC是什么,后来回家查了下才知道是flash的一种类型,这个没弄过就是不知道。也不要不懂装懂了,老老实实查查以后知道就可以了。不过做这个的现在实在是不知道多不多,CSDN上看过有人讨论,但是具体情况也不明;

总结到这里算告一段落,欢迎大家继续讨论,添加一些新的面试例子给大家共享一下。呵呵。祝大家新年快乐。来年步步高升事业有成!

原文地址:https://www.cnblogs.com/mercuryxu/p/1666877.html