<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>

          Linux驅(qū)動(dòng)程序的數(shù)據(jù)封裝

          共 3802字,需瀏覽 8分鐘

           ·

          2021-11-15 16:58

          引言

          0
          基于ARM內(nèi)核的SoC在引入設(shè)備樹技術(shù)之后,通過設(shè)備樹文件來描述不同的設(shè)備并匹配不同的驅(qū)動(dòng)代碼,使得一個(gè)kernel鏡像文件可以支持多種設(shè)備。這種代碼可重用的思想不僅體現(xiàn)在設(shè)備樹文件中,在驅(qū)動(dòng)代碼中同樣也有所體現(xiàn)。其中之一就是驅(qū)動(dòng)代碼中設(shè)備描述表-of_device_id。同一個(gè)IP集成到不同SoC或者根據(jù)應(yīng)用場景激活不同功能,可以通過of_device_id這個(gè)數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)。

          對(duì)于同一個(gè)IP集成到不同SoC的應(yīng)用場景而言,其寄存器基地址以及時(shí)鐘等參數(shù)可能不同,但是IP功能基本一樣。那么可以通過of_device_id里的不同data條目獲取對(duì)應(yīng)的參數(shù)信息。例如exynos的dsi IP,在不同版本的SoC中基地址不同,定義了5種SoC類型。在dsi probe時(shí)獲取其在SoC中的基地址。




          下面驅(qū)動(dòng)代碼表示該模塊需要支持多種不同時(shí)鐘頻率的初始化,可以定義一個(gè)of_device_id表,根據(jù)匹配到的設(shè)備信息為每一種時(shí)鐘提供獨(dú)立的初始化函數(shù)。由of_device_id_match_data獲取到不同的init_fn,按照不同的dev.of_node,執(zhí)行return init_fn(np);


          以上應(yīng)用場景核心的數(shù)據(jù)結(jié)構(gòu)是of_device_id,關(guān)鍵的處理函數(shù)是of_device_get_match_data(),當(dāng)然,關(guān)于of_device_id的應(yīng)用場景不僅僅限于上面說的這兩種。


          數(shù)據(jù)結(jié)構(gòu)of_device_id

          1
          of_device_id數(shù)據(jù)結(jié)構(gòu)如下,定義在mod_devicetable.h中,組成也并不復(fù)雜。
          1struct?of_device_id?{
          2????char????name[32];
          3????char????type[32];
          4????char????compatible[128];
          5????const?void?*data;
          6};


          mod_devicetable.h這個(gè)文件最初并沒有of_device_id這個(gè)數(shù)據(jù)結(jié)構(gòu),該文件的歷史暫時(shí)也只能查到2005年的Linux-2.6.12-rc2



          它的功能從最初的文件中也可以看到,主要是為PCI以及USB設(shè)備使用的,將設(shè)備的vendor ID、subsystem ID、class等信息提供給scripts/table2alias.c,當(dāng)系統(tǒng)新插入一個(gè)PCI或USB設(shè)備時(shí),用戶空間程序根據(jù)對(duì)應(yīng)的vendor ID等信息來加載對(duì)應(yīng)的驅(qū)動(dòng)程序。


          2005年7月Linux-2.6.13-rc2中提交了of_match_id這個(gè)數(shù)據(jù)結(jié)構(gòu)的代碼。


          ???????? of_device_get_match_data()

          2
          函數(shù)原型位于drivers/of/device.c
           1const?void?*of_device_get_match_data(
          2????const?struct?device?*dev)

          3
          {
          4????const?struct?of_device_id?*match;
          5
          6????match?=?of_match_device(xxx);
          7????if?(!match)
          8????????return?NULL;
          9
          10????return?match->data;
          11}
          12EXPORT_SYMBOL(of_device_get_match_data);


          這個(gè)函數(shù)的返回值類型可強(qiáng)制轉(zhuǎn)換成任何類型,取決于驅(qū)動(dòng)程序中例化數(shù)據(jù)結(jié)構(gòu)of_device_id data。當(dāng)然,由于of_device_get_match_data的函數(shù)返回值類型決定了不做強(qiáng)制類型轉(zhuǎn)換,也不會(huì)有問題。

          代碼中增加下面的內(nèi)容,來追蹤of_device_get_match_data執(zhí)行流程。


          #定義of_device_id并完成例化


          #在probe函數(shù)中增加獲取數(shù)據(jù)的代碼


          執(zhí)行結(jié)果顯示正確的獲取到了of_device_id各個(gè)成員例化的value值


          #of_device_get_match_data()代碼流程


          有幾種情況是無法獲取到數(shù)據(jù)的
          ##解析dtb之后未創(chuàng)建設(shè)備結(jié)點(diǎn)
          ##驅(qū)動(dòng)代碼未實(shí)現(xiàn)of_device_id設(shè)備表
          ##of_device_id成員compatible、name、type的值和設(shè)備樹中定義的同

          基于模塊加載的并且可以熱插拔的驅(qū)動(dòng)程序,可以在系統(tǒng)啟動(dòng)后查看設(shè)備表信息。以定位出未獲取到設(shè)備表信息的故障原因。


          查看設(shè)備表信息

          3
          能夠查看到設(shè)備表信息的一個(gè)前置條件是在定義of_device_id的時(shí)候,要將該設(shè)備表通過MODULE_DEVICE_TABLE來進(jìn)行聲明注冊(cè),否則在用戶空間是看不到的。其定義在/include/linux/module.h中。type可以是of、usb、pci等,name為設(shè)備表的名字。


          內(nèi)核中scripts/mod/file2alias.c,用于將設(shè)備表導(dǎo)出到用戶空間modules.alias中,所以可以直接查看modules.alias文件。

          也可以通過modinfo來查看ko文件符號(hào)信息



          設(shè)備表的定義如下,代碼定義了name、type,那么設(shè)備樹里同樣也要定義:


          刪除MODULE_DEVICE_TABLE,modules.alias里是沒有設(shè)備表信息的。




          對(duì)于of_device_id而言,name、type、compatible添加的方法:



          #USB設(shè)備表
          1struct?usb_device_id?{
          2????/*?which?fields?to?match?against??*/
          3????__u16???????match_flags;
          4
          5????/*?Used?for?product?specific?matches;?range?is?inclusive?*/
          6????__u16???????idVendor;
          7????__u16???????idProduct;
          8????__u16???????bcdDevice_lo;
          9????__u16???????bcdDevice_hi;
          10
          11????/*?Used?for?device?class?matches?*/
          12????__u8????????bDeviceClass;
          13????__u8????????bDeviceSubClass;
          14????__u8????????bDeviceProtocol;
          15
          16????/*?Used?for?interface?class?matches?*/
          17????__u8????????bInterfaceClass;
          18????__u8????????bInterfaceSubClass;
          19????__u8????????bInterfaceProtocol;
          20
          21????/*?Used?for?vendor-specific?interface?matches?*/
          22????__u8????????bInterfaceNumber;
          23
          24????/*?not?matched?against?*/
          25????kernel_ulong_t??driver_info
          26????????__attribute__((aligned(sizeof(kernel_ulong_t))));
          27};

          #PCI設(shè)備表
          1struct?pci_device_id?{
          2????__u32?vendor,?device;???????/*?Vendor?and?device?ID?or?PCI_ANY_ID*/
          3????__u32?subvendor,?subdevice;?/*?Subsystem?ID's?or?PCI_ANY_ID?*/
          4????__u32?class,?class_mask;????/*?(class,subclass,prog-if)?triplet?*/
          5????kernel_ulong_t?driver_data;?/*?Data?private?to?the?driver?*/
          6};


          對(duì)于這兩種類型的設(shè)備,導(dǎo)出的符號(hào)信息和普通設(shè)備也不一樣。

          PCI設(shè)備導(dǎo)出到用戶空間的設(shè)備信息:


          導(dǎo)出PCI設(shè)備信息的代碼


          USB設(shè)備導(dǎo)出到用戶空間的設(shè)備信息:



          導(dǎo)出USB設(shè)備信息的代碼


          除了上面三種設(shè)備描述table之外,kernel還提供了很多種其他的設(shè)備描述表,定義在include/linux/mod_devicetable.h



          mod_devicetable.h的commit log:
          https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/include/linux/mod_devicetable.h




          推薦閱讀:

          專輯|Linux文章匯總
          專輯|程序人生
          專輯|C語言
          我的知識(shí)小密圈

          關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤鏈接。

          歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~
          瀏覽 73
          點(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>
                  小泬BBBB免费看 | 色综合高清在线观看视频 | 中文字幕一区二区三区日本在线 | 91AV视频播放 | 91嫩草私人成人亚洲影院 |