当前位置: 首页 > Linux

宋宝华:Linux设备驱动框架中的设计模式——模板方法(TemplateMethod)

时间:2023-04-06 23:58:34 Linux

本文转载,版权归作者所有。商业转载请联系作者授权,非商业转载请注明出处。作者:宋宝华来源:微信公众号linux代码阅读领域(id:linuxdev)前言《设计模式》这本经典书籍定义了20多种设计模式。虽然都是面向对象的,但看起来需要C++、Java等语言才能实现,但是根据作者的一再强调,Linux内核虽然是用C语言和汇编语言编写的,但实际上充满了面向对象的设计无处不在。面向对象与其说是一种语言,不如说是一种思想。我们可以在C中实现巨大的OO,而Linux内核中到处都有OO。模板法例如在Linux的设备驱动框架中,使用了一个非常经典和简单的设计模式——模板法(TemplateMethod),当然还有一些其他的设计模式。设计模式的伟大之处在于,专家们经常会在不经意间使用设计模式,而他们甚至都不知道。如果高手没有系统学习过设计模式,这不一定是问题。这并不是说它不懂设计模式,只是他不知道自己用的是哪种模式。学习设计模式的最终目的当然是忘记设计模式。这和修炼独孤九剑没什么区别。到头来,其实没有什么招数能赢。模板方法模式强调定义一个实现通用流程和算法的基类。比如做一件事情需要经过step1()、step2()、step3()。然后我们定义一个基类:里面的step1(),step2(),step3(),step4()如何实现因人而异,所以我们从继承baseClass类()的类中实现step1,step2(),step3()代码,覆盖baseClass中的函数。这样的设计让外界不关心derivedClass,因为进程和接口都在基类中。基类实现的doSomething()成员函数是一个对外接口。这个UML关系很简单:驱动case在Linux设备驱动中,类似的设计还有很多。我们以NAND为例。在drivers/mtd/nand/nand_base.c层中,定义了NAND??的一些操作流程。比如写OOB代码:需要经过cmdfunc(),write_buf(),cmdfunc(),waitfunc()这些步骤,这些步骤,不管世界上哪种NAND硬件,都是一样通用的,但是具体针对不同的NAND硬件控制器,这些步骤中涉及的cmdfunc()等函数的实现方法因人而异。比如freescale版本的fsl_elbc_nand.c是:nand_base.c,这个C文件是NAND的中间层,和我们前面说的实现baseClass层的代码非常相似,而nand_write_oob_std函数和baseClass类似::做一点事。Linux驱动中定义的nand_chip的不同NAND控制器,nand_chip结构体中的成员函数cmdfunc()、write_buf()等的实现不同,类似于step1()和step2()。nand_chip定义在include/linux/mtd/nand.h中:这样设计的好处是非常明显的。具体的硬件只负责自己运行相关的事情,而一般的流程由nand_base来处理,最大限度地减少了具体实例的代码量,最大程度的复用了中间层的代码。像这样的例子比比皆是,比如我们在LCD的中间层:本文后记与前言不符,请见谅。最近有不少童鞋问笔者,linux驱动有前途吗?作者明确告诉大家:根本没有未来!但是未来是自己挣来的,这要看你是从driver那里进去的,而是从更大的角度:通过做driver去理解很多OO架构的设计思想,升华你对高内聚低耦合的理解,转自己成为更高级的软件工程师;通过做司机,可以进一步了解Linux自身的进程、内存、IO等知识,升华对软件系统和性能分析的理解,使自己成为更高层次的技术专家。如果你开了5年车,进去的时候调试寄存器,用示波器,出来还是调寄存器,用示波器,那自然是没有前途的!有没有未来,这件事因人而异。未来无所谓,无所谓。如果你有抽象和推导的能力,有不断学习和总结的精神,不管你会不会开车,都会是一件很有前途的事情。相反,做任何事情基本上都没有前途。更多精彩更新来袭……欢迎关注微信公众号:linux代码阅读田(id:linuxdev)