解决一个驱动代码解耦合问题
之前解決的項(xiàng)目LCD設(shè)備兼容問(wèn)題,在 a.c 文件里面定義了一個(gè)變量,然后在 b.c 里面使用 extern聲明引用這個(gè)變量,通過(guò)這種方法可以在b.c中使用在a.c 里面初始化的變量。
但是這中情況就會(huì)引起一個(gè)問(wèn)題,就是驅(qū)動(dòng)代碼之間耦合了,這也違背了驅(qū)動(dòng)代碼 高內(nèi)聚、低耦合的思想。
所以,這篇文章就是討論解決這個(gè)問(wèn)題的。
之前寫(xiě)的文章
LCD驅(qū)動(dòng)兼容
1、先說(shuō)說(shuō)問(wèn)題產(chǎn)生的本質(zhì)
在 a.c 驅(qū)動(dòng)文件中,我會(huì)根據(jù) dts 文件的配置掛載一個(gè)platform 驅(qū)動(dòng),這個(gè)驅(qū)動(dòng)獲取dts文件的 gpio口信息,申請(qǐng)gpio口,并賦值給 g_lcm_power變量。
代碼如下
dts文件
?panel:?panel@0?{compatible?=?"hx8279d";gpio_lcd_pwr_en?=?<&pio?47?0>;status?=?"okay";};驅(qū)動(dòng)文件
static?const?struct?of_device_id?lcm_platform_of_match[]?=?{{.compatible?=?"hx8279d",.data?=?0,},?{/*?sentinel?*/} };MODULE_DEVICE_TABLE(of,?platform_of_match);static?int?lcm_platform_probe(struct?platform_device?*pdev) {const?struct?of_device_id?*id;enum?of_gpio_flags?flags;int?ret;struct?device_node?*node?=?pdev->dev.of_node;PRINTFx("[Kernel/LCM]?lcm_platform_probe()?enter\n");id?=?of_match_node(lcm_platform_of_match,?pdev->dev.of_node);if?(!id)return?-ENODEV;g_lcm_power?=?of_get_named_gpio_flags(node,?"gpio_lcd_pwr_en",?0,?&flags);if?(!gpio_is_valid(g_lcm_power))?{dev_err(&pdev->dev,?"invalid?en?gpio%d\n",?g_lcm_power);}ret?=?devm_gpio_request(&pdev->dev,?g_lcm_power,?"gpio_lcd_pwr_en");if?(ret)?{dev_err(&pdev->dev,"failed?to?request?GPIO%d?for?relay-en-gpio\n",g_lcm_power);return?-EINVAL;}return?0; }static?struct?platform_driver?lcm_driver?=?{.probe?=?lcm_platform_probe,.driver?=?{.name?=?"hx8279d",.owner?=?THIS_MODULE,.of_match_table?=?lcm_platform_of_match,}, };static?int?__init?lcm_init(void) {PRINTFx("[Kernel/LCM]?lcm_init()?probe?enter\n");/*if?(platform_driver_register(&lcm_driver))?{PRINTFx("LCM:?failed?to?register?this?driver!\n");return?-ENODEV;}*/return?0; }static?void?__exit?lcm_exit(void) {platform_driver_unregister(&lcm_driver); }late_initcall(lcm_init); module_exit(lcm_exit); MODULE_AUTHOR("mediatek"); MODULE_DESCRIPTION("LCM?display?subsystem?driver"); MODULE_LICENSE("GPL");a.c 文件 和 b.c 文件的只能執(zhí)行一個(gè)lcm 驅(qū)動(dòng),具體執(zhí)行哪個(gè)驅(qū)動(dòng)是在lk判斷硬件接了哪一個(gè)硬件模組,所以我們?cè)趯?shí)現(xiàn)驅(qū)動(dòng)代碼的時(shí)候,a.c驅(qū)動(dòng)文件和b.c驅(qū)動(dòng)文件都需要具備注冊(cè)上述說(shuō)的那個(gè) power gpio代碼,用來(lái)控制模組的電源。
我的解決辦法是
在 a.c 驅(qū)動(dòng)文件中,我會(huì)根據(jù) dts 文件的配置掛載一個(gè)platform 驅(qū)動(dòng),這個(gè)驅(qū)動(dòng)獲取dts文件的 gpio口信息,申請(qǐng)gpio口,并賦值給 g_lcm_power變量。
因?yàn)閍.c的platform驅(qū)動(dòng)我是默認(rèn)每次開(kāi)機(jī)都會(huì)加載。
在b.c驅(qū)動(dòng)文件中,我使用 extern int g_lcm_power;來(lái)聲明這個(gè)變量,這樣做之后,如果在lk識(shí)別到b.c的驅(qū)動(dòng),這個(gè)變量也可以正常使用。
2、什么是高內(nèi)聚、低耦合?
什么是高內(nèi)聚、低耦合?
這是之前寫(xiě)的一篇文章,我覺(jué)得解釋的比較不錯(cuò)了。
3、如何解決這樣的問(wèn)題?
如何解決,也就是說(shuō)我們要對(duì)驅(qū)動(dòng)代碼進(jìn)行解耦合。
因?yàn)槲覀兇a中就只對(duì)一個(gè)對(duì)GPIO口的控制,如果脫離DTS的注冊(cè),直接在驅(qū)動(dòng)文件里面對(duì)這個(gè)GPIO口進(jìn)行操作的話,理論上就可以解決耦合的問(wèn)題了。
這部分可以去查一下下面這個(gè)函數(shù)
gpio_direction_output測(cè)試看看如果在不申請(qǐng)的情況下是否可以使用。
第二種情況就還是使用dts來(lái)匹配
dts改成如下
?panel:?panel@0?{/*compatible?=?"hx8279d";*/gpio_lcd_pwr_en?=?<&pio?47?0>;status?=?"okay";};在 a.c 和 b.c 驅(qū)動(dòng)中,同時(shí)使用如下代碼申請(qǐng)gpio口,linux的dts是一個(gè)很不錯(cuò)組織結(jié)構(gòu),也有很多函數(shù)來(lái)獲取dts中的文件。
想研究dts的同學(xué),可以看看這個(gè)目錄下的內(nèi)容,對(duì)大家調(diào)試非常有幫助。
static?void?lcm_init_power(void) {struct?device_node?*panel_nd;int?ret;enum?of_gpio_flags?flags;PRINTFx("[Kernel/LCM]?lcm_init_power()?enter\n");/*查找整個(gè)dts文件,找到panel,前面是NULL就是讓這個(gè)函數(shù)查找整個(gè)dts*/panel_nd?=?of_find_node_by_name(NULL,?"panel");if(!panel_nd){PRINTFx("Can't?file?panel_nd?node\n");return;}/*獲取gpio_lcd_pwr_en屬性信息*/g_lcm_power?=?of_get_named_gpio_flags(panel_nd,?"gpio_lcd_pwr_en",?0,?&flags);PRINTFx("1212121g_lcm_power=%d\n",?g_lcm_power);if?(!gpio_is_valid(g_lcm_power))?{PRINTFx("invalid?en?gpio%d\n",?g_lcm_power);return;}ret?=?gpio_request(?g_lcm_power,?"gpio_lcd_pwr_en");if?(ret)?{PRINTFx("failed?to?request?GPIO%d?for?relay-en-gpio\n",g_lcm_power);return;}PRINTFx("[Kernel/LCM]?lcm_init_power()?end\n");return; #ifndef?BUILD_LKPRINTFx("[Kernel/LCM]?lcm_init()?enter\n"); #endif }推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語(yǔ)言
我的知識(shí)小密圈
總結(jié)
以上是生活随笔為你收集整理的解决一个驱动代码解耦合问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 单片机外围模块漫谈之二,如何提高ADC转
- 下一篇: redis 常用配置文件配置