<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          解決一個(gè)驅(qū)動(dòng)代碼解耦合問(wèn)題

          共 3601字,需瀏覽 8分鐘

           ·

          2021-01-27 05:37

          之前解決的項(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)行操作的話(huà),理論上就可以解決耦合的問(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_LK
          ?PRINTFx("[Kernel/LCM]?lcm_init()?enter\n");
          #endif
          }



          推薦閱讀:
          專(zhuān)輯|Linux文章匯總
          專(zhuān)輯|程序人生
          專(zhuān)輯|C語(yǔ)言
          我的知識(shí)小密圈



          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久婷婷综合国产色视频 | 国内一级免费黄色视频在线网展览器的封 | 做爱视频网 | 99精品A√| 在线天堂资源 |