当前位置: 首页 > Linux

宋宝华:转发声明(ForwardDeclaration)

时间:2023-04-07 00:52:53 Linux

广泛应用于Linux内核编程本文转载,版权归作者所有。商业转载请联系作者授权,非商业转载请注明出处。作者:宋宝华来源:微信公众号linux代码阅读领域(id:linuxdev)前向声明编程法强调一点:在所有可能的场景中,尽可能使用前向声明(ForwardDeclaration)。这符合信息隐匿原则。regmap示例那么前向声明到底是什么?在内核中写代码和看代码的童鞋们经常会发现Linux内核中充斥着这样的代码,比如在include/vimlinux/regulator/driver.h文件中:下面以regmap的结构为例。这个地方是一个forward语句告诉下面的代码,regmap是一个结构体。至于这个结构里面是什么,我就不知道了!Linux可以说全世界都在使用这种结构。include/linux/regmap.h中声明的regmap_write()和regmap_read()等API正在全世界使用。可以说是无处不在,无处不在,比如在drivers/rtc/rtc-at91sam9.c:这样的东西随便搜索一下,可以找到无数。看来regmap的结构应该是一个跨模块的API。它的整个结构是什么样子的?它应该出现在include/linux/这一层的顶层跨模块头文件中,方便跨模块引用这个结构。然而,真实情况却出乎你的意料。regmap结构的具体成员是什么样子的,并没有出现在任何外部级别的头文件中,完全是内部的(internal,internal,internal,童鞋们!!!):drivers/base/regmap/internal.h因为它出现在drivers/base/regmap/internal.h中,除了drivers/base/regmap/本身内部实现/regmap/internal.h这个头文件外,肯定是不可能在外部引用drivers/base的。所以,我们得出一个结论,虽然全世界Linux都在用structregmap,但是除了drivers/base/regmap/里面,其实外面没有人知道regmap的结构是什么样子的!!这是一个极其优秀的“高内聚、低耦合”的设计。因为,drivers/base/regmap/之外的所有人实际上只有指向regmap结构的指针,而没有访问regmap结构的任何成员。其实他们只有内部实现drivers/base/regmap/访问而已。例如regmap_write的实现在:drivers/base/regmap/regmap.c文件中,其代码如下:这样做带来的一个很大的好处就是drivers/base/regmap/的外部世界不需要知道lengthoftheregmapstructure是什么样子的,因为没有人需要知道,他们都只是在访问regmap指针!但是无论在drivers/base/regmap/内部如何修改regmap结构体的实现和成员,对于外界来说是完全不可见的。修改regmap结构后,drivers/base/regmap/以外的模块不需要重新编译!相反,如果我们直接在include/linux/regmap.h头文件中暴露regmap结构的内部细节,那么由于这个头文件全世界都在引用,只要修改regmap结构本身,会导致内核中无数个模块增量编译!regmap_config结构体暴露在include/linux/regmap.h中,也就是说这个结构体的内容需要被regmap以外的模块知道:...为什么,涉及到具体寄存器的读写回调和具体的寄存器模式,这肯定是基本API的东西,应该是跨模块的东西,所以它的出现出现在顶层头文件include/linux/regmap.h中。对于一个外部模块,它只需要能够通过regmap.h公开暴露一小部分寄存器配置接口,通过regmap_init_mmio()这样的API来填充regmap结构的内部实现。比如在drivers/rtc/rtc-at91sam9.c中:上面代码中,rtc->gpbr是一个structregmap指针,regmap_init_mmio()里面填充的是regmap本身的实现。之后drivers/rtc/rtc-at91sam9.c调用regmap_write()和regmap_read()时,这些API会调用我们从regmap模块中填写的寄存器模式reg_bits、val_bits和reg_stride,帮助完成最后的读写寄存器。画图理清关系,始终以高内聚低耦合的思路设计代码。Linux内核2000万行代码,如果不这样设计,肯定会崩溃。写代码不糊涂。尤其是写单片机裸奔程序的童鞋要特别注意。你常常认为玩Linux的童鞋代码很傻,这是完全不正确的理解。每天都要带娃,没时间写,就拿时间的碎片胡说八道,不知道评委怎么看?欢迎搬砖,也欢迎打赏。更多精彩更新来袭……欢迎关注微信公众号:linux代码阅读田(id:linuxdev)