新聞動態(tài)

免費谘詢熱線

13621929115
常見(jiàn)問題
您的位置: 主頁 > 新聞動(dòng)態 > 常見問題

工廠設備沙盤

發布日期:2023-04-04 23:04瀏覽次數:


    Linux設備模型是對(duì)係統(tǒng)設備組(zǔ)織架構進行抽象的一個數據結構,旨在為設備驅動進行分層、分類、組織降低設備多樣性帶來的Linux驅動開(kāi)發(fā)的複雜度(dù),以及設備熱拔插處(chù)理、電源管理等Overview設計目的電源管(guǎn)理和(hé)係統關機(Power management and system shutdown)

    設備之間工廠設備沙盤大多情況下有依賴、耦合,因此要實現電源管理就必須對(duì)係統的設備結構有清楚的理解,應(yīng)知道先關哪個然後(hòu)才能再(zài)關哪個設計設備模型(xíng)就是為了使係統可(kě)以按(àn)照(zhào)正確順序進行硬件(jiàn)的遍曆(lì)與用戶(hù)空間的(de)交互(hù)(Communications with user space)。

    實現了sysfs虛擬文件係統它可以將設備模型中定義的設工廠設備沙盤備屬性信息等(děng)導出到用戶空間,使得在用戶空間可以(yǐ)實現對設備屬性的訪問及參數(shù)的更改詳(xiáng)見Documentation/filesystems/sysfs.txt。

    可熱插拔設備(Hotpluggable devices)設備模型管理內核(hé)所使用的處(chù)理用戶空間熱(rè)插拔的機製,支持設備的動(dòng)態添(tiān)加與移除設備類別(Dev工廠設備(bèi)沙盤ice classes)係統的許多(duō)部分對設備如何連接(jiē)沒有興(xìng)趣, 但是它們需要知道什麽類型的(de)設備可用。

    設備模型也實現了一個給設備分類的機製, 它(tā)在一個更高的(de)功能性級別描述了這些設備對象生命期(Object lifecycles)設備模型的實現一(yī)套機製(zhì)來處理對象生(shēng)命期設備模型框圖Linux 設備模型是一(yī)工(gōng)廠設備沙盤個複雜的數據結(jié)構。

    如圖所示為和USB鼠(shǔ)標相關聯的設備模型的一小部分:

    這個框圖展示了(le)設備模型最重要的四個部分的組織關係(在頂層容器中詳解):Devices描述了設備如何連接到係統Drivers係統中可用的驅動Buses跟蹤什麽連接到(dào)每個總線,負責匹配設(shè)備與驅動classes。

    設備底層細節的抽象(xiàng),描述了工廠設備沙盤(pán)設(shè)備所提供的功能底層(céng)實(shí)現kobject作用與目的Kobject是將整個設備模型連(lián)接在一起的基礎主要用來實現以下功能:對象的引用計數(Reference counting of objects)。

    通(tōng)常, 當一個內核(hé)對象被創建, 沒(méi)有方法知道它會(huì)存在多長時間 一種跟蹤這種對象生命周期的方法是通過引用計數工廠設備(bèi)沙盤 當(dāng)沒有內核代碼持有對給定對象的(de)引(yǐn)用, 那個對象已經完成(chéng)了它的有用壽命(mìng)並(bìng)且可以被刪除sysfs 表示(Sysfs representation)。

    在sysfs中顯示的每一個項目都是(shì)通過一(yī)個與內核交(jiāo)互的kobject實現的數據結構粘和(Data structure glue)設備模型整(zhěng)體來看是一個極(jí)端(duān)工廠(chǎng)設備沙盤複(fù)雜的由多級組成的數據結構, kobject實現各級之間的(de)連接(jiē)粘和。

    熱插拔事件處理(Hotplug event handling)kobject處理熱插拔事件並通知用戶空間數據結構/* include in */struct kobject {    。

    constchar *name; /* 該ko工廠設(shè)備沙盤bject的名稱,同時也是sysfs中的目錄名稱 */struct list_head entry; /* kobjetct雙(shuāng)向鏈表 */struct kobject *parent;

    /* 指向kset中的kobject,相(xiàng)當於指向父目錄 */struct kset *kset; /*指向所屬的ks工(gōng)廠設備沙盤et*/struct kobj_type *ktype; /*負責對kobject結構跟蹤*/

    ...

        };/* 定義kobject的(de)類型及釋放回調 */struct kobj_type {    void (*release)(struct kobject *); /* kobjec工廠設備沙盤t釋放函數指針 */

    struct sysfs_ops *sysfs_ops; /* 默認屬性操作方法 */struct attribute **default_attrs; /* 默認屬(shǔ)性 */};/* kobject上(shàng)層容器 */

    struct kset {    

           struc工廠設備沙盤t list_head list; /* 用於連接kset中所有kobject的鏈表頭 */spinlock_t list_lock; /* 掃描kobject組成(chéng)的鏈表時使用(yòng)的(de)鎖 */

    struct kobject kobj; /* 嵌入的(de)kobject */conststruct kset_uev工廠設備沙(shā)盤ent_ops *uevent_ops; /* kset的uevent操作(zuò) */};/* 包含kset的更高級(jí)抽象(xiàng) */

    struct subsystem {    struct kset kset; /* 定義一個kset */struct rw_semaphore rwsem; /* 用於串行訪問工廠(chǎng)設備(bèi)沙盤kset內部鏈表的讀寫信號量 */

    };kobject和kset關係:

    如圖所示,kset將它(tā)的children(kobjects)組成一個標準的內核鏈表所以說(shuō)kset是一(yī)個(gè)包含嵌入在(zài)同種類型結構中(zhōng)的kobject的(de)集合它自身也內嵌一個kobject,所(suǒ)以也(yě)是一個特(tè)殊的(de)kobject。

    設計kset的(de)主要工廠設(shè)備沙盤目的是容納(nà),可以說是kobject的頂層(céng)容器kset總(zǒng)是會在sysfs中以目錄的形(xíng)式呈現需要注意的是(shì)圖中所示的kobject其實是嵌入在其他類型(xíng)中(很少單獨(dú)使用),也可能是其他(tā)kset中。

    kset和subsystem關係:一(yī)個子係統subsystem, 其實隻是一個附加了個讀寫信號量的kset的(de)包裝工廠設備沙盤,反過來(lái)就是說每個 kset 必須屬於一個(gè)子係統根據subsystem之間的成員關(guān)係建立kset在(zài)整個層級中的位(wèi)置。

    子(zǐ)係統常常使用宏(hóng)直接靜態(tài)定義:/* 定義一個struct subsystem name_subsys 並初始化kset的type及hotplug_ops */

           d工廠設備沙盤ecl_subsys(name,

    struct kobj_type *type,struct kset_hotplug_ops *hotplug_ops);操(cāo)作函數初始化/* 初始(shǐ)化kobject內部結構 */void kobject_init(

    struct kobject *kobj);/* 設(shè)置n工廠設備沙盤ame */int kobject_set_name(struct kobject *kobj, constchar *format, ...);

    /* 先將kobj->kset指向(xiàng)要添加的(de)kset中,然後調(diào)用會將kobject加(jiā)入到指定的kset中 */int kobject_add(struct 工廠設備沙盤kobject *kobj);/* kobject_register = kobject_init + kobject_add */

    extern int kobject_register(struct kobject *kobj);/* 對應(yīng)的Kobject刪除函數 */void kobject_d工廠設備沙盤el(struct kobject *kobj)

    ;void kobject_unregister(struct kobject *kobj);/* 與kobject類似的kset操作函數 */void kset_init(struct kset *kset)

    ;

        kobject_set工廠設備沙盤_name(&my_set->kobj, "The name");int kset_add(struct kset *kset);int kset_register(struct

    kset *kset);void kset_unregister(struct kset *kset);Tip: 初始(shǐ)化前工廠設備(bèi)沙盤應先使用memset將kobj清(qīng)零;初始化完成後引用計數為1引用計數管理/* 引用計數加1並返回指向kobject的指針 */

    struct kobject *kobject_get(struct kobject *kobj);/* 當一個引用被釋放, 調用(yòng)kobject_put遞減引用計數,當引用為工廠設備沙盤(pán)0時(shí)free這(zhè)個object */

    void kobject_put(struct kobject *kobj);/* 與kobject類似的kset操作函數 */struct kset *kset_get(struct kset *kset)

    ;void kset_put(struct kset *k工廠設(shè)備沙盤set);釋放當(dāng)引用計數為0時,會調用(yòng)ktype中的release,因此可以(yǐ)這樣定義release回調函數:void my_object_release(

    struct kobject *kobj){    struct my_object *mine = container_of(kobj, str工廠設備沙盤uct my_object, kobj);    /* Perform any additional cleanup on this object, then... */

    kfree(mine);

        }/* 查找ktype */struct kobj_type *get_ktype(st工廠設備沙(shā)盤ruct kobject *kobj);subsystem相關(guān)decl_subsys(name, type, hotplug_ops);

    void subsystem_init(struct subsystem *subsys);int subsystem_register(struct subsys工廠設備沙盤tem *subsys);void subsystem_unregister(

    struct subsystem *subsys);struct subsystem *subsys_get(struct subsystem *subsys);void subsys_put(struct

    subsyste工廠設備(bèi)沙盤m *subsys);Low-Level Sysfs Operationskobject和sysfs關係kobject是實現sysfs虛(xū)擬文件係(xì)統背後(hòu)的機製sysfs中的每一個目錄都對應內(nèi)核中的一個kobject。

    將kobject的屬性(atrributes)導出就會在sysfs對應的目錄(lù)下產生由內工(gōng)廠設備沙盤核自動生成的包(bāo)含這些屬性信息的文件隻需簡單的調用前麵所提到的kobject_add就會在sysfs中生成一個對應kobject的(de)入口,但值(zhí)得注(zhù)意的是:。

    這個入口總會以目錄呈(chéng)現, 也就是說生成一個入口就是創建一個目錄通(tōng)常這個目錄會包含一個或多個屬性文件(見下文)分配給kobject的(de)名字(用kobje工(gōng)廠設備沙盤ct_set_name)就(jiù)是給 sysfs 目錄使用的名字,因此在sysfs層級中相同部分的kobject命名必須唯一,不能包含(hán)下劃線,避免使用空格。

    這個入口所處的目錄表示kobject的parent指針,如果parent為NULL,則指向的是它的kset,因此可以(yǐ)說(shuō)sysfs的層級其實對應的就是k工廠設(shè)備沙盤set的層級但當kset也為NULL時,這個入口就會創建在sysfs的top level,不過實際中很(hěn)少出現這種情況。

    屬性(atrributes)屬性即為上麵(miàn)所(suǒ)提到的一旦導出就會由內核自動生成的包含(hán)kobject內核信息(xī)的文件結構如下:struct attribute {    char *name工廠設(shè)備(bèi)沙盤; /* 屬性名,也是sysfs對應entry下的文件名 */。

    struct module *owner; /* 指向負責實現這個屬性的模塊 */mode_t mode; /* 權限位,在中定義 */};屬性的導出顯示及導入存儲函數:/* kobj: 需要處理的kobject

          a工(gōng)廠設(shè)備沙(shā)盤ttr: 需要處理的屬性

          buffer: 存儲編碼後的屬性信息,大(dà)小為PAGE_SIZE

          return: 實際編碼的屬性信息長度

          */

    struct sysfs_ops {    ssize_t (*show)(struct kobject 工廠設備沙盤*kobj, struct attribute *attr,char *buffer); /* 導出到用(yòng)戶空間 */

    ssize_t (*store)(struct kobject *kobj, struct attribute *attr,constchar *buffer, size_t size工廠設備沙盤); /* 存儲進內核空(kōng)間(jiān) */

    };需要注意的是:每(měi)個屬性都是用name=value表示,name即使屬性的文件名,value即文件(jiàn)內(nèi)容,如果value超過PAGE_SIZE,則應分為多個屬性來處理;上述函數可以處理不同(tóng)的屬性可以在內部實現時同過屬(shǔ)性名進行區(qū)分來實現(xiàn);。

    由於store是從用戶空間到內工廠設備沙盤核,所以實(shí)現時首先要檢查(chá)參數的合法行,以免(miǎn)內核崩潰及其(qí)他問題缺省屬性(Default Attributes)在kobject創(chuàng)建時都會賦予一些缺省的默認屬(shǔ)性,即上麵所提(tí)到的kobj_type中的default_attrs數組,這個數組的最(zuì)後一個成員須設置成NULL,以表示數(shù)組大小。

    所有使用這個kob工廠設備沙盤j_type的(de)kobject都是通過kobj_type中(zhōng)的sfsfs_ops回調函數入口實現對缺(quē)省屬性的定(dìng)義非缺省屬性(Nondefault Attributes)一般來說,定義時就可以通過default_attrs完成所(suǒ)有的屬性,但這裏也(yě)提(tí)供了後(hòu)續(xù)動態添加和(hé)刪除屬性的方法:

    int sysfs_cr工廠設備沙盤eate_file(struct kobject *kobj, struct attribute *attr);   int sysfs_remove_file(struct kobject *kobj,

    struct attribute *attr);二進製屬性(Binary Attributes)工廠設備沙盤上述屬性包含的可讀的文(wén)本值,二進製屬(shǔ)性很少使用,大多用在從(cóng)用戶空間傳遞一些不改動的文件如firmware給設備的情況下。

    struct bin_attribute {            struct attribute attr; /* 定義name,owner,mode */size_t siz工廠設備沙(shā)盤e; /* 屬性最大長度,如沒有(yǒu)最大長(zhǎng)度則設為(wéi)0 */

    ssize_t (*read)(struct kobject *kobj, char *buffer,loff_t pos, size_t size);            ssize_t (*write)(

    struct kobject *ko工(gōng)廠設備沙盤bj, char *buffer,loff_t pos, size_t size);

               };read/write一次加載多次調用,每次最多PAGE_SIZE大(dà)小。

    注意write無法指示最後一個寫操作,得通過其他方式判斷操作的結束二進製屬性不能定義為缺省值,因此需(xū)明確的創建工廠設備沙盤與刪除:int sysfs_create_bin_file(struct kobject *kobj,

    struct bin_attribute *attr);        int sysfs_remove_bin_file(struct kobject *kobj,struct bin_attri工廠設備沙盤(pán)bute *attr)

    ;符號連接(Symbolic Links)方法:int sysfs_create_link(struct kobject *kobj, struct kobject *target,char *name)

    ;    void sysfs_remove_link(struct ko工廠設備(bèi)沙盤bject *kobj, char *name);熱插拔事件生成(Hotplug Event Generation)熱插拔事件即當係統配置發生改變是內核向用戶空間的通知。

    然後用戶空間會調用/sbin/hotplug通過創(chuàng)建節點、加載(zǎi)驅動等動作進(jìn)行響應這個熱插拔(bá)事件的產生(shēng)是在kobject_add和k工廠設備沙盤object_del時www.17C.com可以通過上麵(miàn)kset中定義的uevent_ops對熱插拔事件產生(shēng)進行配置:。

    struct kset_uevent_ops {    /* 實現事件的過濾,其返回值為0時不產(chǎn)生事件 */int (* const filter)(struct kset *kset, struc工廠設備沙盤t kobject *kobj);

    /* 生成傳(chuán)遞給(gěi)/sbin/hotplug的name參數 */constchar *(* const name)(struct kset *kset, struct kobject *kobj);    

    /* 其他傳遞給/sbin/hotplug的(de)參數通過這種設置環境變量(liàng)的工廠設備沙盤方(fāng)式傳遞 */int (* const uevent)(struct kset *kset, struct kobject *kobj,

    struct kobj_uevent_env *env);

        };頂層容器(qì)Buses, Devices, Drivers and ClassesBus工(gōng)廠(chǎng)設備(bèi)沙盤es總線Buses是處理器(qì)和設備的(de)通道在(zài)設備模型中,所有設備都是通過總線(xiàn)連接在一起的,哪怕是(shì)一個內部虛擬(nǐ)的platform總線。

    /* defined in   */struct bus_type {    

           constchar *name; /* 總線類型名 */struct 工廠設備沙盤bus_attribute *bus_attrs;

    /* 總線的屬性 */struct device_attribute *dev_attrs; /* 設備(bèi)屬性,為每個加入總線的設備建立屬性鏈表(biǎo) */struct driver_attribute *drv_attrs; 

    /* 驅動屬性,為每個加入總線的工廠設備沙盤驅動建立屬性鏈表 *//* 驅動(dòng)與設備(bèi)匹配函數:當一個新設備或者驅動被添加到(dào)這個總線時,

              這個(gè)方法會被調用一次或(huò)多次,若(ruò)指定的(de)驅動程序能夠處理指定的設備,則返(fǎn)回非零值。

    必須在(zài)總線層使用這個函數, 因為那裏存在正確的邏輯,核心內核不知(zhī)道如何為每個總線類型匹配設備和(hé)驅動程(chéng)序 工廠設備沙盤*/int (*match)(struct device *dev, struct

    device_driver *drv);


           /*在為用戶空間產生熱插拔事(shì)件之前,這個方法允許總線添加環(huán)境變量(參數和 kset 的uevent方法相同)*/int (*uevent)(struct工廠設備沙盤

     device *dev, struct kobj_uevent_env *env);    

           ...    struct subsys_private *p; /* 一(yī)個很重要的域,包含了(le)device鏈表和drivers鏈表 */

    }/* 定義bus_attrs的快捷方式 */B工廠設備沙盤US_ATTR(name, mode, show, store);/* bus屬(shǔ)性文件的創建移除 */int bus_create_file(struct

    bus_type *bus, struct bus_attribute *attr);void bus_remove_file(struct bu工廠設備沙盤s_type *bus, struct bus_attribute *attr)

    ;/* 總線注冊(cè) */int bus_register(struct bus_type *bus);void bus_unregister(struct bus_type *bus);/* 遍曆總線上的設備與驅(qū)動 */

    i工廠設備沙盤nt bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int(*fn)(struct device *,

    void *));int bus_for_each_drv(struct bus_type *bu工廠設備沙盤(pán)s, struct device_driver *start, void *data, int(*fn)(

    struct device_driver *, void *));DevicesLinux中,每一個(gè)底層設備都是structure device的一個實例:struct device {    工廠設備沙盤 struct

     device *parent; /* 父設(shè)備,總線設備指定為NULL */struct device_private *p; /* 包含設備鏈表(biǎo),driver_data(驅動程(chéng)序要使用數據)等信息 */

    struct kobject kobj;    

            const工廠設備沙盤char *init_name; /* 初始默認的(de)設備名 */struct bus_type *bus; /* type of bus device is on */

    struct device_driver *driver; /* which driver has allocated this de工廠設(shè)備沙(shā)盤vice */

            ...     void (*release)(

    struct device *dev);

        };int device_register(struct device *dev);void device_unregister(struct devic工廠設備沙盤e *dev)

    ;


        DEVICE_ATTR(name, mode, show, store);int device_create_file(struct device *device,struct device_attribute *entry)

    ;void device_remove工廠設備沙盤_file(struct device *dev,struct device_attribute *attr);Drivers設備模型跟蹤(zōng)所有係統已知的驅動struct。

    device_driver {    

           constchar *name; /* 驅動名稱,在sysfs中以(yǐ)文工廠設備沙盤件(jiàn)夾名出現 */struct bus_type *bus; /* 驅動(dòng)關聯(lián)的總線類型 */

    int (*probe) (struct device *dev); /* 查詢(xún)設備的存在 */int (*remove) (struct device *dev); /* 設備移除回調 */void (*sh工廠設備沙(shā)盤utdown) (

    struct device *dev);

           ...

        }int driver_register(struct device_driver *drv);void driver_unregister(struct

    device_driver *drv);工廠設備沙(shā)盤


        DRIVER_ATTR(name, mode, show, store);int driver_create_file(struct device_driver *drv,

    struct driver_attribute *attr);void driver_remove_file工廠設備沙盤(struct device_driver *drv,struct driver_attribute *attr)

    ;Classes類是(shì)設備的一個高級視(shì)圖,實現了底層(céng)細節通過對設備進行分(fèn)類,同(tóng)類代碼可共享,減(jiǎn)少了內核(hé)代碼的冗餘(yú)structclass {    constchar      *name;工廠設備沙盤 /* class的(de)名稱,會在“/sys/class/”目錄下體現 */。

    struct class_attribute      *class_attrs;    struct device_attribute     *dev_attrs; /* 該class下每個設備的attribute */

    s工廠設備沙盤truct kobject          *dev_kobj;    /* 當(dāng)該class下有設備(bèi)發生變(biàn)化時,會調用class的uevent回(huí)調函數 */int (*dev_uevent)(struct

    device *dev, struct kobj_uevent_env *env);    c工廠設備(bèi)沙盤har *(*devnode)(struct device *dev, mode_t *mode);

    void (*class_release)(structclass *class);    void (*dev_release)(struct device *dev);    int (*susp工(gōng)廠設備沙盤end)(

    struct device *dev, pm_message_t state);    int (*resume)(struct device *dev);    struct class_private *p;

        };

    int class_register(structcla工廠設備沙盤ss *cls);void class_unregister(structclass *cls);


        CLASS_ATTR(name, mode, show, store);

    int class_create_file(structclass *cls,conststruct clas工廠設備沙盤s_attribute *attr);void class_remove_file(struct

    class *cls,conststruct class_attribute *attr);Putting It All Together

    嵌入式Linux中文站最專業的中文嵌入式Linux網(wǎng)站,8年磨(mó)劍,工廠設備沙盤注冊用戶數萬人!分享嵌入式 & Linux技(jì)術幹貨、教程、資訊(xùn)、高薪職位訂(dìng)閱點(diǎn)擊標題下方“嵌入式Linux中文站”分(fèn)享點擊右上角按鈕投稿


標簽:

產品推薦

Copyright © 2002-2020 上海潤之模型設計(jì)有限公司 版(bǎn)權所有 展示模型(xíng),展品模型,展(zhǎn)廳模型,展示道(dào)具,展廳展品,展品道具,模(mó)型定製,模型公司,上海模型公司 備案號:滬ICP備20018260號

13621929115
网站地图 www.17C.com_17.C-起草网登录在线_17c.一起草 在线观看视频_17c.com免费观看入口