2006年研究生毕业,应聘到一家创办一年半左右的IC Startup公司从事Windows驱动软件的开发工作.
我们驱动组(我和我的师傅两个人)所面对的是一个全新项目,Microsoft AVStream/BDA 架构的USB dongle TV tuner驱动程序的开发.
现在回过头来想想,作为一名软件工程师,要能很好地把这个项目完成,必须具备以下多个方面的知识:
第一方面:是与USB相关的方面
USB2.0(至少是Protocol层),
USB audio class协议,(该项目不需要USB video class协议的基础,但能了解更好)
USB InterOP/Golden Tree测试过程
第二方面:是与Windows系统相关的方面
Windows WDM驱动程序模型,Windows内核基本原理,Windows内核调试的方法(当时用的是SoftICE,后来随着WinDbg的渐渐强大与反之SoftICE的衰败,转入到使用COM口来双机调试),
Windows WHQL(现在已经更名为WHCK,这是为了获取微软驱动程序认证,技术含量不大,但作为商业软件却又是必须的,能发现驱动中的许多问题,你必须在客户challenge你之前,作好必须与必需的准备),还有Driver Verifier的工作原理与使用。
第三方面:
有了第二方面的基础,再加上必备的英文文档阅读能力,再去谈AVStream/BDA PCTV架构的理解与掌握
在这个方面中,必须学会Microsoft的
GraphEdit的使用,它是AVStream/BDA的实际体现
我们在增加驱动中IR遥控器功能时,也就需要使用GraphEdit.
第四方面:是了解数字电视,音视频编解码基本概念与知识
它包括:NTSC/PAL, ATSC/DVB/DTMB, CVBS/SVideo, BT656,TS码流,MPEG, I2S/AC97/PWM, QAM等
公司里有调制解调方面的世界级专家,也有Video/Audio decoder的资深专业工程师,了解这些不是为了班门弄斧,是为了在驱动编码中的正确使用.我一直提倡学以至用,以实际项目为依托,带着问题去学习,一切的纸上谈兵,盲目地读源代码基本上都是浪费时间,到最后多是竹篮打水.
第五方面:是相关chip的编程
包括Cypress FX2(MCU51, GPIF, I2C), AU0828 , 多种Tuner的配置方法(包括Microtune, NXP, Maxlinear, Xceive等业界主要的Silicon tuners,以及一些Can tuners).
第六方面:C++的编程
Microsoft 所给出的AVStream/BDA驱动框架是C++的形式,较C而言,使用C++的Class能够更加方便地管理驱动中所使用到的各种功能与属性,例如AVStream/BDA中的每一个Filter,每一个Pin.同时,由于我们的这一款驱动需要支持多种方案,那么每一款Tuner,每一款Demodulater, 都有一个class的instance.
之后,我们要将USB dongle TV tuner的驱动与PCI/PCIe/PCMCIA TV card驱动代码集成,也就用到了C++中的继承与多态.
而初出茅庐的我掌握这些必备知识中的哪些呢?
答案是little.
玩过一阵子Philips的USB1.1 chip PDIUSBD12
,主要是firmware,只是对USB有了初步的应用了解.
之后,玩了一阵子Cypress的USB2.0 chip FX2LP.
使用FX2LP所包含的GPIF,I2C,MCU51,USB High speed功能,再加上ADI的DAC构建了一个具体图像数据传输项目.
做这个实际项目的过程中,伴随着问题的出现与解决,进一步了解了USB协议(比如尝试将图像数据传输从BULK IN转到ISO IN的方案),尝试着修改Cypress所提供的USB driver以解决ISO图像数据传输的实际需求,GPIF与实际外设接口,状态机的设计,上层图像应用软件与驱动的衔接等等.
说到这里,我想到前阵子部门老板说的一句话:在他面试刚刚毕业的学生的时候,主要看他的思路是否清晰,而非着重考察他/她掌握了哪些与多少知识(部门老板在中国团队的ALL HANDS MEETING上,说话非常有霸气,给人的感觉是,有帅才).事实也确实是这样,一个刚毕业的学生能否胜任一份工作,与他的举一反三实际应用能力关系特别大,所以work smart是work hard的前提.
在之后的几年中,就是本着举一反三的原则,又做了以下几个项目:
第一:
因为AVStream架构的Analog TV驱动与USB audio class Native Windows driver分别服务于USB dongle TV tuner device的两个Interface,所以,当ATV压力测试到一定时间,就会产生音视频不同步的现象,于是我们设计与实现了一个USB audio class lower filter driver,在音频数据即将送给上层TV Player前,filter driver偷偷地将这一份音频数据COPY送给了ATV驱动,以实现驱动程序这一关的音视频同步要求.
这个项目,反而比AVStream/BDA驱动简单,因为它就是WDM filter架构的驱动,但是,必须考虑到非常重要的两点要求:
一,对多实例(多个USB Dongle的支持);
二, upper filter与lower filter存在一定差别的,特别是在如何处理来自外部驱动或者APP的IRPs时,所以,在这里,我们必须使用windows control objecter的技术.(具体请参看Microsoft的相关KB文章)
第二:
使用Cypress slave FIFO接口,实现数据验证平台
由于有了Cypress GPIF I(USB2.0 chip FX2LP是GPIF Gen 1, USB3.0 chip就是更加复杂的GPIF Gen 2,以后我会专门花时间写一写Cypress的GPIF)的实用经验,使用slave FIFO相当于a piece of cake.
主要的就是做好与FPGA工程师的Communication,制定一个较合理的接口协议.
第三:
Linux V4L2/DVB项目
说到底层软件工程师的工作内容,不得不说Linux,近些年Android的需求量聚增,导致了公司对Linux/Android工程师的大量扩招,但就本着当初PCTV这个项目,Linux驱动程序的客户,是放到support list中最低优先级,这个最低优先级并不是由我们公司,或者老板的个人因素决定的,是由于市场与客户决定的.
所以,这个项目,是在一种不紧不慢的氛围中蹒跚的.
还是需要举一反三,smart work,与Linux驱动工程师合作,将现有而且成熟,稳定,可靠,已经通过WHQL认证的Windows驱动PORT到Linux V4L2/DVB上面不是一件很难的事情.
题外话,前阵子OSR NTDEV List(从事Windows内核开发,必须常去的地方),对于"Windows工程师,是否需要学习Linux"的TOPIC,TOPIC发起者的原因是,现在市场上对LINUX的需求量聚增,基本是利益驱动,而Windows驱动职位不如以前那么火了。
我的意见是,举一反“2”,有了任何一操作系统的实际经验,跳到另外一个方面,都不是特别难的事情.
你理解了DPC,就理解了Soft Interrupt.
难道你掌握了Linux中的stack的使用,你还不能将它应用于windows kernel dump中对stack overflow的分析?
难道你了解了Windows中的分页机制,你就不能快速地掌握Linux内存管理的相关内容?
如果你的答案是,YES,我只能说,你的老板看错人了.
也就是前几天,有人听到Windows 8/8.1可以运行在ARM上表示惊讶,他的惊讶也间接表露了他的OUT.
同时,对于这个TOPIC,我的观点是,这个社会上的专业人才,是以金字塔状分布与呈现的,底层对技术的初步了解,中层对技术的熟练运用,到顶层,深刻理解整个系统(软件,硬件,或者是软硬件)如何设计,为何这样设计,对系统中出现的关键问题,策手问题的分析与解决的人数是收敛的,这就需要在extensive的基础上,做intensive的研究.
之后的工作内容,发生了看似本质上的变化(我没有去做sales,marketing),实则万变不离其宗.
面对Base Graphic Windows driver, STB Linux driver, USB3.0 SS IP developing software engineer三个OFFERs, 最后选择了IP developing.
几点原因:
一,没有从事过IP developing,新鲜感.
二,可以对USB有进一步了解.
三,基本上和USB dongle PCTV项目一样,是比较新的项目,刚刚开始不久,能够了解更多的为什么,而不是维护工作。
四,老板在USB方面的水平.
五,USB总归要用到Windows驱动,包括USB storage, audio, video。
在USB DEVICE IP项目时,Windows8还没有上市,没有xHCI驱动,也没有UAS驱动,所以就需要开发一款UAS的Windows驱动。
在USB3.0 xHCI项目时,需要使用WinDbg对带有我们的xHCI USB3.0 host IP的Windows 8 or 8.1系统进行 Kernel Dump分析,而且这成了我的一项主要的工作内容.
后期篇章,我将推出我使用WinDbg这把"柳叶刀"对一些System Kernel Dump file的分析实例,敬请关注与斧正.
最后感谢我的第一任老板,与我的第一位师傅。希望我的这篇文章,对刚刚踏出校园,准备从事底层软件工作的学生有所帮助。
“调试难度本来就是写代码的两倍.因此,如果你写代码的时候聪明用尽,根据定义,你就没有能耐去调试它了.” – Brian Kernighan