免费高清特黄a大片,九一h片在线免费看,a免费国产一级特黄aa大,国产精品国产主播在线观看,成人精品一区久久久久,一级特黄aa大片,俄罗斯无遮挡一级毛片

分享

Linux設(shè)備模型(總線、設(shè)備、驅(qū)動程序和類)之一:bus

 WUCANADA 2012-12-01

Linux設(shè)備模型(總線、設(shè)備、驅(qū)動程序和類)之一:bus_type

分類: Linux驅(qū)動 1139人閱讀 評論(0) 收藏 舉報

      總線是處理器和一個或多個設(shè)備之間的通道,在設(shè)備模型中,所有的設(shè)備都通過總線相連,甚至是內(nèi)部的虛擬"platform"總線??梢酝ㄟ^ls -l /sys/bus看到系統(tǒng)加載的所有總線。
drwxr-xr-x root     root              1970-01-01 00:02 platform
drwxr-xr-x root     root              1970-01-01 00:02 spi
drwxr-xr-x root     root              1970-01-01 00:02 scsi
drwxr-xr-x root     root              1970-01-01 00:02 usb
drwxr-xr-x root     root              1970-01-01 00:02 serio
drwxr-xr-x root     root              1970-01-01 00:02 i2c
drwxr-xr-x root     root              1970-01-01 00:02 mmc
drwxr-xr-x root     root              1970-01-01 00:02 sdio
drwxr-xr-x root     root              1970-01-01 00:02 ac97
      總線可以相互插入。設(shè)備模型展示了總線和它們所控制的設(shè)備之間的實際連接。在Linux 設(shè)備模型中,總線由bus_type 結(jié)構(gòu)表示,定義在 <linux/device.h> :
struct bus_type {
    const char  *name;                            /*總線類型名稱*/
    struct bus_attribute *bus_attrs;       /*總線屬性*/
    struct device_attribute *dev_attrs;   /*設(shè)備屬性,指為每個加入總線的設(shè)備建立的默認屬性鏈表*/
    struct driver_attribute *drv_attrs;     /*驅(qū)動程序?qū)傩?/

    int (*match)(struct device *dev, struct device_driver *drv);   /*總線操作函數(shù)*/
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev);
    void (*shutdown)(struct device *dev);

 

    int (*suspend)(struct device *dev, pm_message_t state);    /*電源管理函數(shù)*/
    int (*suspend_late)(struct device *dev, pm_message_t state);
    int (*resume_early)(struct device *dev);
    int (*resume)(struct device *dev);
    struct pm_ext_ops *pm;
    struct bus_type_private *p;
};
1,總線的注冊和刪除,總線的主要注冊步驟:
(1)申明和初始化bus_type 結(jié)構(gòu)體。只有很少的bus_type 成員需要初始化,大部分都由設(shè)備模型核心控制。但必須為總線指定名字及一些必要的方法。例如:
struct bus_type ldd_bus_type = {
    .name = "ldd",
    .match = ldd_match,
    .uevent = ldd_uevent,
};
(2)調(diào)用bus_register函數(shù)注冊總線。int bus_register(struct bus_type *bus),該調(diào)用可能失敗,所以必須始終檢查返回值。
ret = bus_register(&ldd_bus_type);
if (ret)
   return ret;
若成功,新的總線子系統(tǒng)將被添加進系統(tǒng),之后可以向總線添加設(shè)備。當(dāng)必須從系統(tǒng)中刪除一個總線時,調(diào)用:
void bus_unregister(struct bus_type *bus);


 2,總線方法
     在 bus_type 結(jié)構(gòu)中定義了許多方法,它們允許總線核心作為設(shè)備核心與單獨的驅(qū)動程序之間提供服務(wù)的中介,主要介紹以下兩個方法: int (*match)(struct device * dev, struct device_driver * drv);
/*當(dāng)一個新設(shè)備或者驅(qū)動被添加到這個總線時,這個方法會被調(diào)用一次或多次,若指定的驅(qū)動程序能夠處理指定的設(shè)備,則返回非零值。*/
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
/*在為用戶空間產(chǎn)生熱插拔事件之前,這個方法允許總線添加環(huán)境變量*/

      對設(shè)備和驅(qū)動的迭代:若要編寫總線層代碼,可能不得不對所有已經(jīng)注冊到總線的設(shè)備或驅(qū)動進行一些迭代操作,這可能需要仔細研究嵌入到 bus_type 結(jié)構(gòu)中的其他數(shù)據(jù)結(jié)構(gòu),但最好使用內(nèi)核提供的輔助函數(shù):
int 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 *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver *, void *));
/* 這兩個函數(shù)迭代總線上的每個設(shè)備或驅(qū)動程序(內(nèi)部分別有next_device和next_driver),將關(guān)聯(lián)的device或 device_driver傳遞給 fn,同時傳遞data 值。若start為NULL,則從第一個設(shè)備開始;否則從start之后的第一個設(shè)備開始。若fn返回非零值,迭代停止并且那個值從 bus_for_each_dev 或bus_for_each_drv 返回。*/
 

3,總線屬性

     幾乎Linux 設(shè)備模型中的每一層都提供添加屬性的函數(shù),總線層也不例外。bus_attribute 類型定義在<linux/device.h> 如下:

struct bus_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct bus_type *, char * buf);
    ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};
     內(nèi)核提供了一個宏在編譯時創(chuàng)建和初始化bus_attribute 結(jié)構(gòu):

BUS_ATTR(_name,_mode,_show,_store)/*這個宏聲明一個結(jié)構(gòu),將bus_attr_作為給定_name 的前綴來創(chuàng)建總線的真正名稱*/
/*總線的屬性必須顯式調(diào)用bus_create_file 來創(chuàng)建:*/
int bus_create_file(struct bus_type *bus, struct bus_attribute *attr);
/*刪除總線的屬性調(diào)用:*/
void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr); 
      例如創(chuàng)建一個包含源碼版本號簡單屬性方法如下:

static ssize_t show_bus_version(struct bus_type *bus, char *buf)
{
      return snprintf(buf, PAGE_SIZE, "%s/n", Version);
}

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL); //得到bus_attr_version

/*在模塊加載時創(chuàng)建屬性文件:*/
if (bus_create_file(&ldd_bus_type, &bus_attr_version))
      printk(KERN_NOTICE "Unable to create version attribute/n");

/*這個調(diào)用創(chuàng)建一個包含 lddbus 代碼的版本號的屬性文件(/sys/bus/ldd/version)*/
 

 

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/funy_liu/archive/2010/02/25/5322040.aspx

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多