忆nandflash的失败
年底了,该总结这一年的收获与失败。
今年主要做的一个项目是P500.并负责其中的nandflash模块。
nandflash:一种存储芯片。P500支持将系统文件烧录到该存储芯片中。nandflash由于工艺的原因导致本身在烧录过程中不稳定,烧录的数据易发生位翻转。或者某个区域极其不稳定的现象。所以就需要在烧录的时候有ECC进行校验,还有BBM(俗称坏块管理)进行管理区域极其不稳定的块。(块是nandflash本身能够管理的区域的最小单位)。
初始状态:
1、我加入这个项目组的时候,项目组的其他成员,其他模块已经做得差不多了。
2、我对这个nandflash模块的需求很不清晰。
3、加入该项目的时候手上还有另外要维护的项目跟要进行技术支持的手持机相关东西。
自己在这个项目中角色的融入过程:
1、因为对这个项目的需求不熟悉,对框架也不是很了解。所以刚开始的时候也不知道从哪里下手。但是该项目的老大说:你先把烧录nand的流程编写出来。其他就很简单了。但是我发现我根本没办法写出该流程。现在回想起来应该是我考虑的太多了:简单流程就是简单流程,就不去想其他的东西了。
2、因为该模块要依赖的东西有:导入的要烧录的文件模块、描述nand芯片的数据库和要烧录到芯片时,通过的中间层(时序接口)。而跟我配合开发的时序人员(对nand的业务很熟悉)一直没空,当然也有我个人的原因:就是不会很主动的去问该如何操作。这个我应该要改的地方。初到项目组,在需求不懂,业务不清楚的情况下,还不敢死皮赖脸的去问。所以导致的问题是:数据库我根本没有通过规范文档来制作(本应该由时序人员来进行制作的,后来却变成了一个生手来完成这个操作,当然了这样的结果导致了数据库在描述芯片信息的时候,描述的乱七八糟,虽然芯片信息都有了)。然后时序接口的底层,也是由我跟我老大还有另一个同事来调试,而不是由真正的那位懂得时序的人员来进行编写跟调试。最后导致的结果也是该时序的调试过程进行的很慢。
3、对nandflash的数据结构,定义的很不合理。首先:我参照了另一个nandflash的烧录平台(6000F)的数据结构的封装方式进行编写数据结构,然后学6000F的访问数据的方式进行访问。对于我的这个愚蠢行为我只能无限的自责。关于对自己的该行为进行愚蠢的描述得追溯到我一直在维护这个6000F软件。当维护该软件时,我一直在吐槽该软件的设计者,为何会设计出如此低劣的软件时候。回过头来我竟然去参照了该软件的数据结构的设计方式跟访问方法。以至于最近我还在无限的自责,为此已经从上周开始天天自己加班或者周末自己去办公室进行修改数据结构的设计方式。
关于数据结构的封装,在我看来数据结构是怎样的,作为用户应该不需要去关心,用户需要的只是获取该数据的接口。而不是直接去读取数据库的数据(导致耦合性非常大)。然后读取跟写入文件的方式也不应该直接操作底层的接口,作为用户,应该能够做的只是把数据扔给指定的写入接口。这样不管底层数据库的结构如何改变,用户层都不用去更改相应的代码。关于这次的失误,其实给根结底是我对该nandflash的需求还不够清晰,而导致了只能完全依赖老软件的设计方法,然后自己在加以改良的时候却只是修改了一点点,没有做到彻底的修改。
4、对界面的设计,起初逻辑跟界面耦合度太大了。由于时间太赶,而自己也没想太多,直接进行编码。可以说是自己编写的太随意了,虽然在指定的时间内完成了功能。但是因为界面总是需要修改的,而导致了相应的逻辑也相应的进行了修改。并且在设计该界面的时候,该项目的老大给的界面设计的建议跟跟我配合的时序人员给的建议完全不一样。而我却没有一点的主见,刚开始听从老大的建议写了一套。后来时序人员完全不满意,然后又重新写了一套。最后,搞得自己的心特别累。关于这个,具体我应该听谁的,更应该是时序人员。毕竟他对nandflash的业务比较熟悉。但是在我跟他熟悉之后,我发现一个特点:因为时序人员不是写软件的,所以对软件的一些概念很不熟悉,有些功能其实应该舍弃的,因为那些功能对大部分的客户根本就不会用到。在几千个客户中,也许就那么一两个客户会用到,并且对于这两个客户,和增加的软件设计复杂度相比投入成本是过大的。当然后来某些功能还是直接放弃了,但是中间被他影响而导致逻辑设计上更加复杂了。当然,这个也不能怪他,毕竟他要的是该软件是万能的,什么客户都能支持,但是有这样子的软件的话,那很容易就可以想到研发成本会提高多少。只能说我自己经验还是太少了,不懂得去评估跟取舍。所以如果有下次跟别人一起做软件的时候,对于功能的实现,需要进行一定的评估。
5、对烧录流程的设计,其实到目前为止还是一团乱。关于烧录流程,我这里一直在修改。我发现了一个问题:我沿用了我最初的简单的烧录的方式。虽然循序渐进的进行迭代了好几次。但是都没能走出那个最初烧录方式的那个怪圈。一直在最初的版本上面进行修改。并且过早的考虑该nandflash的速度问题。而导致刚开始的设计过于复杂。
如果现在让我重新设计烧录接口的话:我会将各个烧录方式进行相应的模块化,而不是在字节中进行每个位的计算,异或等操作。这样的操作没过几天就差不多忘记到底这些异或或者位计算是什么意思。又或者迷惑了自己。
6、对于插件(BBM或者ECC)的操作接口,做的还不够合理。虽然相对来说已经够简单了,但是为了用户的使用方便,我设计的太过复杂。
总结:
0、在拿到一个项目之后,应该要至少广泛的了解该项目要做成什么样,需求大致是什么样子的。哪些点需要注意,哪些点需要舍弃。
1、对于不熟悉的业务,一定要主动去咨询,对于是别人的工作一定要强烈要求对方去做,否则自己做完的结果是:吃力又不讨好。
2、在参照别人的代码的时候,觉得设计的不好的时候,需要重新以自己的思路去思考考如何设计。而不是想着怎样在别人的基础上修改的好一点(这样子的结果导致了最终设计出来的其实跟别人代码的思想几乎一样换汤不换药)。
3、对于做任何操作的时候,决不能让客户代码操作底层,一旦涉及到底层了,说明设计的有问题了,需要修改对应的设计方案。
4、对于觉得迭代了好几次都没设计好的,最好舍弃,重新设计。否则最终会引发更严重的问题。也导致了用户无法对该代码进行阅读跟修改。
5、关于重构:觉得设计不合理的地方一定要马上去重构,而不是说要等到把这个项目做得差不多的时候再进行相应的修改。这样会导致项目很危险。设计不合理马上重构。
收获:
1、有了一定的工程概念。也有了一些的项目经验。
2、学到了一些新的技术(学到的技术最多的是来自项目)。
3、知道了需求的重要性。
4、学会去取舍一些东西。
5、一定要去看重构这本书。这本书不只是维护人员需要看,编写代码人员也需要看。因为编写软件就是一直在重构的过程。
ps:C++的技术其实自己该学到的其实也差不多,虽不敢说精通,但是好歹也算是熟悉了。但是项目经验缺很欠缺。从做这个P500的项目就可以看出来。