转眼就工作一年了,还是简单总结下这一年来都干了些啥吧。
做事篇
进公司的前四个月基本上都是在培训,内容基本上分为两类,一类和产品相关,主要是熟悉公司产品,以WR841N系列无线路由器为主,做了很多实验,了解了很多以前只停留在表面的知识,比如DHCP/PPPoE/ARP/TFTP等协议,经过四个月的培训后,实事求是的说,对这些协议的了解要比在学校光看书得来的理解深刻的多了。另一个培训重点是跟工作相关的技能,核心内容是Linux下的C编程、内核编程和脚本编程,脚本这一块主要是shell,经历四个月的培训,系统编程和脚本编程这一块也有了不少的提高。
刚到公司时,整个软件研发部还未进行拆分重组,当时所进的组是Linux组,其实现在很怀念在这个组时的状态,Linux组的氛围非常open,大家有什么问题都可以拿出来一起讨论,无论是老员工还是新员工,几乎都能打成一片,遇到一个有分歧的问题,整个组的人常常可以在邮件中讨论得热火朝天,而且绝不会因为对问题的见解不一样而出现矛盾,对事不对人的风气非常的不错,可惜,不久之后公司人事调整,离具体产品线较远的Linux组被拆散,人员被分别并入到了其他负责具体产品线的组内。
在Linux组时负责的工作比较杂,主要经手了3G路由器项目的USB模式切换模块的开发和维护。3G路由器项目是随着3G在国内市场的铺开而上马的,其中的一个重点模块就是3G USB Modem的模式切换。这个问题之所以存在,是因为市面上的大多数3G USB Modem都采用了这样的工作模式:第一次接到PC上时,表现为一个CD ROM设备,在这个“伪”CD ROM上存有3G USB Modem的驱动程序,用户可以安装驱动程序,安装完成之后,3G USB Modem自动从“伪”CD ROM设备切换成Modem模式,此时就可以正常的拨号上网了。在PC上,Windows系统提供了对3G USB Modem设备自动切换设备模式的支持,但Linux并没有提供自动切换USB设备工作模式的能力,这就要求我司3G路由器具备自动切换USB设备模式的功能。
问题是:USB设备的模式切换,并不是一个标准的设备功能,各厂家的3G USB Modem实现自动模式切换的方法不一样,各种各样的方法都有,因此,尽管不可能做到兼容市场上所有的3G USB Modem,但至少需要达到的目标是:对市场上主流的3G USB Modem,都需要能支持(至少不能比竞争对手能够支持的3G USB Modem数量少)。
另一个难点是:要找出USB设备模式切换的途径,基本上只能通过逆向工程的办法来完成。这方面,网络上有一些资源可以利用:一个是SniffUSB项目,该项目提供了一个用于嗅探USB通信过程的工具;另一个项目是usb_modeswitch,该项目的目标就是要实现3G USB Modem在Linux平台下的切换。
补充一点USB的背景:USB总线协议的协议层有一点类似有线网络,是通过packet在USB设备之间完成通信和控制,这样,就可以像在网络上使用抓包工具(如wireshark, ethereal, tcpdump)捕捉网络通信的数据包一样,也可以通过特殊的工具捕捉USB设备之间的数据包,并对其进行分析。在3G路由器项目中,使用的USB抓包工具就是前面提到的SniffUSB。通过对捕捉到的通信数据包的分析,可以得到一些有可能是促成USB设备切换模式的数据包。这个时候,就轮到usb_modeswitch出场了,usb_modeswitch的作用,就是把这些可疑的数据包发送给指定USB设备,看设备是否切换模式,如果发生了,那么我们也就知道应该如何让USB设备切换模式了。
之前已经有同事完成了3G USB Modem模块的部分功能,但尚不完整,只能支持国内华为和中兴的两个3G USB Modem,我的任务是:学习SniffUSB和usb_modeswitch的工作机制,完善代码,支持更多的3G USB Modem。在此过程中,花了不少时间学习USB协议,并为SniffUSB的使用撰写了使用说明(SniffUSB使用起来是比较有挑战性的,因此需要一份文档,以便后续接手的同事有所参考)。分析数据包的阶段,我一开始是采用人肉分析的方式,一条一条地猜测,效率非常的低,后来,有一些经验之后,就总结出了一定的规律,为了减轻人工分析的负担,我编写了Python脚本以辅助分析。
正在3G路由器项目已经能够支持起更多款3G USB Modem的时候,公司人事方面出现了变动,Linux组被拆分了,我转到了无线组。才刚转到无线组不久,就有一个优先级非常高的项目上马,我被选作该项目的成员之一。该项目由公司技术总监梁工亲自挂帅督阵,除梁工外,项目成员仅有两名:我和另一位同事J,项目预估时间大约三个月,但工作量很大,任务非常艰巨。
该项目用一句话来说就是:切换公司原R402有线宽带路由器的芯片方案。原因是:R402有线宽带路由器一直采用M公司的芯片方案,但M公司的芯片已经停产,并且M公司的这个方案一直存在着性价比低的问题(芯片本身就比较贵,加之支持价格更低廉的SPI Flash还有困难,导致成本难以压缩),公司决定切换到性价比更高的R公司的芯片方案上。我们的目标是:保证原R402路由器上的所有既有功能,性能不得低于原产品,同时要大幅消减产品成本。经过三个多月的艰苦鏖战,我们最终实现的结果是:成本得以大幅削减(光是芯片本身就省出来了零点几个美刀,换成人民币可就是几块钱呐,这还不算外围器件上的节约),同时新的R406产品的性能相比原R402产品的大多数性能指标都有了令人欣慰的提升。更重要的是,这个项目是一个探路性质的项目,在这款产品完成芯片方案的切换最终量产上市之后,无线、DSL、switch的多款产品的芯片切换项目也陆续展开,都是要用R公司的类似芯片替换旧的芯片方案以压缩成本。这个项目中遇到的难点很多,就研发的角度而言,最主要的困难是核心处理器的架构发生了变化,M公司的芯片是采用ARM架构,而R公司的芯片是MIPS架构的,虽然都是RISC CPU,但仍然需要做很多很多的工作来弥合由于处理器体系结构上的差异所带来的软件移植鸿沟,比如从ARM的Thumb指令模式改为MIPS体系架构的MIPS16指令模式(采用MIPS16在该项目中不是一个可选项,因为这款产品的定位就决定了我们必须严格控制软件最终映像的大小,以确保软件能在512KB Flash、2MB SDRAM这样紧缺的硬件资源上稳定工作);除此之外,开发环境也有很大变动:旧的芯片方案直接使用Tornado开发环境中的工具链就可以了,但现在要支持MIPS16指令,就必须得使用R公司提供的在Cygwin环境下使用的工具链,必须手工修改Makefile和构建脚本等,还必须得处理不同工具链在选项上的差异,显然,这些变化迫使我们得对工具链做更细粒度的控制(比如,由于和硬件关系密切的底层代码不能编译为MIPS16指令模式,本项目必须混合采用MIPS16和MIPS32:大部分上层模块以MIPS16指令模式构建,而底层的BSP部分则以MIPS32指令模式构建,要保证MIPS16与MIPS32之间的无缝融合,不是一件容易的事)。
实战更能锻炼人,经过该项目三个多月的锤炼,我必须得承认,技术水平有了不少的提升。以前在学校的时候虽然也一直在做嵌入式相关的工作,但从来没有这次这么紧张过,对项目质量的要求也从来没有这么严酷过——这三个多月来真是神经高度紧张啊,基本上每天都在争分夺秒的赶进度,不知道加了多少班!(这个项目之所以催进度催得跟打仗似的,根本原因在于M公司的芯片已经停产,市场上已经比较难买到,如果不能及时完成该产品的芯片切换,R402这款产品将面临断货的风险)。再来说质量要求,从三月中旬到四月末,我们前后提交了五轮测试,每轮测试都冒出来一堆bug,bug出来了能怎么办呢,修呗,那段时间基本上是每天一到公司就投入到了捉bug、修bug的战斗中,我们戏称这是一个bug海,我们就像精卫,不停地从远处衔来小石子,要把这个无边无际的bug海填平。
经过一年实际工作的洗礼,我觉得自己在下面这些方面有了提升:
- 摆脱了以前离底层太远的局限,BSP(Board Support Package,板级支持包)开发技术有比较大的进步;
- 对体系结构的理解上了一个台阶,经过三个多月的高强度磨练,对MIPS体系结构经历了从陌生到熟悉的过程,现在的状态是能够轻松自如地阅读MIPS汇编代码(或者ICE反汇编出来的汇编指令);
- 加强了ICE调试工具的掌握,BSP代码的调试过程中大量使用到MENTOR GRAPHICS公司大名鼎鼎的ICE调试工具MAJIC,现在对这款ICE工具的掌握程度基本上可以算是娴熟;
- 加深了对嵌入式OS的理解,基本摸熟了VxWorks及其开发环境。一开始接触VxWorks的时候,对VxWorks那种独特的代码规范甚难接受,及至在VxWorks内核代码浸淫得久了,慢慢也就不再排斥,甚至渐渐开始有点欣赏这个嵌入式OS,虽然代码风格比较另类,但是从内核代码的情况来看,整个系统风格高度统一,基本上看不到随意的代码,代码的模块化、层次化都做得很好,整体质量很高,也难怪VxWorks在工业界得到大量应用;
- 对于如何估算工作量、如何评估风险、如何控制进度、如何管理代码版本、如何管理bug、如何组织测试也有了更多切身的体会,不过这方面的经验仍然非常薄弱,尚需在以后的工作中多总结提高。
虽然这一年来的工作是充实的,但局限也是显而易见的:
- 大部分的工作内容是代码移植,对既有代码做调整居多,从头设计和开发做得相对较少,设计、编码方面的能力有不进反退的危险;
- 做的项目较为单一,视野较为狭窄,工作重心过于靠近底层,缺少了对产品全貌的了解,最近看到公司高层给2010年进公司的应届毕业生培训用的PPT,惊叹于其对公司各个产品理解的深入和广泛,这方面即使在后面的工作中不能有大的提升,也需时刻提醒自己多从产品的角度考虑问题。工作一年,感受极为深刻的一点是:哪怕是一个再小的产品,要想做好,都极不容易;
- 技术方面,钻研深度还远远不够,以R402芯片方案切换项目为例,该项目所用的处理器基于MIPS R3000体系结构,这是MIPS较老的一种架构,现在最新的架构已经有了很大的不同,这些地方都没有机会深入地展开,是为遗憾。
做人篇
虽然从哲学角度说,领导不一定全对,但多数时候领导的观点是应当尊重的,因为位置不同,视角也不同,领导的经验与视野决定了他们常常能够更敏锐地捕捉到问题的本质。在目前接手的一个项目中,我一度花了大量时间解决软件构建过程中出现的错误,也花了大量时间和供应商方面的开发人员沟通,我的部门经理凭其多年的开发经验猜测是我的开发环境和供应商方的环境不一致造成了问题的产生,此后,按照这个思路询问了供应商方面开发环境的设置,并参照供应商提供的配置重新安装了整个开发环境,问题果然迎刃而解。可见,领导能坐到领导的位置上,必然是有其理由的,对领导的意见给予足够的尊重,对于顺利推进工作进程,是有利的。
我得到的另外一个教训是:工作中要顾及他人的感受,不能口无遮拦。说是教训是因为我干过一次这种傻事:在回复同事一封有抄送给部门老大的邮件里面毫不客气地指出了同事贴在邮件中的一段代码中的一个微小错误。虽然事后该同事并未将此事放在心上,但在我回想起来却总觉得这是工作方法和工作技巧不够成熟的表现——类似这种微小的问题私下发邮件给同事说明就可以了,大可不必当着老大在邮件里面直接指出,一来有损同事的面子,二来给人以律己太宽责人太严的坏印象。再说,这也并非是原则问题上的妥协,而只是为人处事方法上的一种技巧罢了。以后的工作中当多多注意。
态度篇
一年的工作,发现以下这些隐性的东西其实蛮重要的。
产品意识:质量控制和成本控制是产品的两大核心主题。不要过分沉迷于好的技术,市场认可的技术才是好技术,无论新旧。
团队意识:bug无论是自己种下的,还是同事埋下的,都是团队的事,要勇于承担。
交流意识:善于交流,事半功倍;埋头苦干,事倍功半,拖累团队进度。工作遇阻,尽量先寻找帮助,对自己是技术难题,对他人也许只是小菜一碟,不要贪恋攻克难题的乐趣而影响工作进度。得人指点,有助于找对方向,避免浪费时间和精力,而且得到的体会也不会少,经验不会因为是通过交流获得的而减弱其分量。
契约精神:不抱怨,不埋怨,不要管别人如何看,坚定地恪守契约精神,既然拿着公司的薪水,就要替公司把事情做好。有个笑话说得好:我假装替老板工作,老板假装给我发薪水——这种态度是断断要不得的。一句话,公司的事就是自己的事。
专业精神:专业,就是高水准。做为一个专业人士,不要容忍自己的工作做得不专业,小到一行代码,一行注释,大到一个产品的功能设计,性能指标,要处处从专业的角度严格要求自己。一个不够专业水准的工程师是不可能得到同行认可的。
重视细节:公司的产品都是以接入型家用路由器为主,产品核心技术其实并不高深,但是经历了这一年来的工作洗礼,深有体会的一点是:一个产品,无论有多小,都必须高度认真的对待,细节决定成败,而魔鬼,就隐藏在细节之中。
价值观:如果能够加速产品进入市场的时间,购买商业软件或者购买方案提供商的技术支持就是值得的。如果商业软件比开源软件更合适,就没必要死守对开源软件的偏爱。宗旨就是,只要是对产品有利的技术、方案、渠道,就是有价值的——只要付出的代价与获得的收益相比较而言是合算的。这和布鲁克斯在《人月神话》中的观点大约是不谋而合的。
工作不能怕麻烦:曾经有段时间,我在工作中遇到比较棘手的问题时,总想找出一条一劳永逸的解决办法,结果是捷径没找到,路倒是绕了一大圈,为此,曾被梁工严肃批评过:如果任务不麻烦,随便找个清洁工都能搞定,那还要我们来干什么。现在想来,梁工是对的。工作中哪有什么捷径,踏踏实实做事就行了,麻烦总是有限的,一个一个攻克过去,总有解决完的一天,如果都梦想着去找什么捷径,也许绕了一大圈又回到原点,徒费无益之功。
展望篇
如果说对未来有什么希望的话,那就是希望下一年的时候,薪水能有所增加,毕竟,一个人对于公司的价值要通过公司付给他的薪酬来反映,我当然是希望自己对公司的价值越多越好。再一个原因是,当家方知柴米贵,深圳的米,更是不一般的贵,居之不易啊,多些薪水,柴米方面也会宽裕些。一言以蔽之,对未来的希望就是:认认真真工作,踏踏实实赚钱,好好生活。
阅读(2464) | 评论(0) | 转发(0) |