日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux内核编程广泛使用的前向声明(Forward Declaration)

發布時間:2023/12/20 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内核编程广泛使用的前向声明(Forward Declaration) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前向聲明

編程定律

先強調一點:

在一切可能的場景,盡可能地使用前向聲明(Forward Declaration)。這符合信息隱蔽的原則。

一個例子

regmap

那么前向聲明究竟是個什么鬼?

在內核寫代碼和看代碼的童鞋,經常發現Linux內核里面充斥著這樣的代碼,比如

include/vim linux/regulator/driver.h

文件中:

我們以regmap這個結構體為例,這個地方就是一個前向聲明,告訴后面的代碼regmap是個結構體,至于這個結構體里面有什么鬼,不知道!

Linux可以說滿世界都在使用這個結構體。滿世界都在使用聲明在include/linux/regmap.h中的regmap_write() regmap_read() 這樣的API,可以說無處不在,無處不用,比如drivers/rtc/rtc-at91sam9.c中的:

這樣的東西大家隨便一搜索,都可以搜索出來無數個。這樣看起來,regmap這個結構體,應該是一個跨模塊的API,它的整個結構體長成怎么樣,應該是出現在一個include/linux/級別的頂級跨模塊頭文件中了,這樣方便跨模塊引用這個結構體。

但是,真實的情況卻讓你大跌眼鏡,regmap結構體的具體成員長什么樣子,沒有出現在任何一個外部級別的頭文件里面,而是完全internal(內部的、內部的、內部的,各位童鞋!!!):

drivers/base/regmap/internal.h

既然它出現在drivers/base/regmap/internal.h,那么想必除了drivers/base/regmap/本身的內部實現外,外部不可能引用drivers/base/regmap/internal.h這個頭文件。

所以,我們得出一個結論,盡管Linux滿世界都在使用struct regmap,但是除了drivers/base/regmap/內部以外,其實外部沒有任何一個人知道regmap這個結構體長成什么樣子!!

這是一種極其良好的高內聚、低耦合」設計。因為,drivers/base/regmap/外部所有的人,其實都只是在擁有regmap這個結構體的指針,而并沒有訪問regmap結構體其中的任何一個成員,其實也只有drivers/base/regmap/的內部實現在訪問而已。

比如,regmap_write實現于:drivers/base/regmap/regmap.c文件,它的代碼如下:

這樣做帶來的一個極大好處是,drivers/base/regmap/外部的世界根本不需要知道regmap結構體長成什么樣子,因為沒人需要知道,它們都只是在訪問regmap的指針。

而drivers/base/regmap/內部無論怎么修改regmap結構體的實現和成員本身,對外部的世界根本不可見,修改regmap結構體后,drivers/base/regmap/以外的模塊都不需要重新編譯。

相反,如果我們直接把regmap結構體的內部細節暴露在include/linux/regmap.h這個頭文件中,那么由于這個頭文件滿世界都被引用,你只要修改regmap結構體本身,就會導致內核無數模塊的增量編譯。

include/linux/regmap.h中暴露了regmap_config結構體,這說明這個結構體的內容需要被regmap以外的模塊知道:

為什么,它涉及到具體的寄存器是如何讀寫的callback以及具體的寄存器pattern,這肯定是一個API基本的東西,本身就應該是跨模塊的東西,所以它的長相出現在了include/linux/regmap.h這個頂級頭文件中。

對于一個外部模塊而言,它只需要能夠通過regmap.h公開暴露的小部分寄存器配置接口,來通過類似regmap_init_mmio()這個的API來填充regmap結構體的內部實現。比如drivers/rtc/rtc-at91sam9.c中的:

上述代碼中,rtc->gpbr是一個struct regmap指針,regmap_init_mmio()在內部填充了regmap的本身實現。之后drivers/rtc/rtc-at91sam9.c再調用regmap_write()、regmap_read()的時候,這些API從regmap模塊內部調用我們填充進去的reg_bits、val_bits、reg_stride這些寄存器pattern,幫忙完成寄存器的最終讀寫。

畫一幅圖

理清關系

永遠用高內聚和低耦合的思想設計代碼。Linux內核2000萬行的代碼,不這么設計肯定要崩盤。寫代碼不是得過且過。尤其做單片機寫裸奔程序的童鞋要特別注意,你們往往覺得玩Linux的童鞋代碼一層層套很傻逼,這是完全不正確的理解。

天天要帶娃,雞飛狗跳,沒時間寫,我隨便用碎片時間胡說八道的,不知道各位看官有什么感想?歡迎板磚,也歡迎打賞。


掃碼或長按關注

回復「?加群?」進入技術群聊

總結

以上是生活随笔為你收集整理的Linux内核编程广泛使用的前向声明(Forward Declaration)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。