5. 驅(qū)動程序分層分離概念-總線設(shè)備驅(qū)動模型

在輸入子系統(tǒng)框架學習中踪蹬,可以看到將其分為上下兩層,和左右兩邊漱牵;這就是我們今天要引入的另一個概念疚漆,驅(qū)動程序的分離分層。


分離分層概念

一闻镶、什么是總線設(shè)備驅(qū)動模型

可以從三個概念丸升,來理解。

  • 總線

?????? 一個總線是處理器和一個或多個設(shè)備之間的通道. 為設(shè)備模型的目的, 所有的設(shè)備都通過一個總線連接, 甚至它是一個內(nèi)部虛擬的"平臺"總線发钝。
?????? 在 Linux 內(nèi)核中, 總線由 bus_type 結(jié)構(gòu)表示, 定義在 <linux/device.h> 。

struct bus_type {
    const char *name; /*總線名稱*/
    int (*match)  (struct device *dev, struct
    device_driver *drv);    /*驅(qū)動與設(shè)備的匹配函數(shù)*/
    ………
}
  • 設(shè)備

代表著一個實際的硬件涛碑。
在 Linux內(nèi)核中, 設(shè)備由struct device結(jié)構(gòu)表示孵淘。

struct device {
{
  const char *init name;  /*設(shè)備的名字*/
  struct bus_type *bus;  /*設(shè)備所在的總線*/
  ………
}
  • 驅(qū)動

代表具體操作設(shè)備的方式和流程。
在 Linux內(nèi)核中, 驅(qū)動由device_driver結(jié)構(gòu)表示:

struct device_driver {
{
    const char *name; /*驅(qū)動名稱*/
    struct bus_type *bus;  /*驅(qū)動程序所在的總線*/
    int (*probe) (struct device *dev);
    ………
}

二揉阎、為什么使用總線設(shè)備驅(qū)動模型

隨著技術(shù)的不斷進步背捌,系統(tǒng)的拓撲結(jié)構(gòu)也越來越復(fù)雜,對熱插拔坑赡,跨平臺移植性的要求也越來越高,2.4內(nèi)核已經(jīng)難以滿足這些需求毅否。為適應(yīng)這種形勢的需要,從Linux 2.6內(nèi)核開始提供了全新的設(shè)備模型徘溢。其優(yōu)勢在于采用了總線的模型對設(shè)備與驅(qū)動進行了管理捆探,提高了程序的可移植性。

三徐许、實例

  • 1.0 總線由bus_type定義(位于<linux/device.h>
struct bus_type {
    const char *name; /*總線名稱*/
    /*總線屬性*/
    struct bus_attribute    *bus_attrs;
    int (*match)  (struct device *dev, struct
    device_driver *drv);    /*驅(qū)動與設(shè)備的匹配函數(shù)*/
    /*為用戶空間產(chǎn)生熱插拔事件之前雌隅,這個方法允許總線添加環(huán)境變量*/
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    ………
}
    1. 1 總線的注冊

bus_register(struct bus_type *bus)
若成功,新的總線將被添加進系統(tǒng)恰起,并可在/sys/bus 下看到相應(yīng)的目錄。

  • 1.2總線的注銷

void bus_unregister(struct bus_type *bus)

  • 1.3總線的匹配

參照bus_type:
int (*match)(struct device * dev, struct device_driver * drv)
當一個新設(shè)備或者新驅(qū)動被添加到這個總線時肯污,該函數(shù)被調(diào)用吨枉。用于判斷指定的驅(qū)動程序是否能處理指定的設(shè)備。若可以貌亭,則返回非零。

創(chuàng)建一條總線:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jalyn Fang");

/*比較設(shè)備的bus_id與驅(qū)動的名字是否匹配锄奢,
匹配一致則在insmod驅(qū)動 時候調(diào)用probe函數(shù)*/
int my_match(struct device *dev, struct device_driver *drv)
{
    return !strncmp(dev->kobj.name,drv->name,strlen(drv->name));
}  

struct bus_type my_bus_type = {
    .name = "my_bus",
    .match = my_match,
};
    
int my_bus_init()
{
    int ret;

    /*注冊總線*/
    ret = bus_register(&my_bus_type);
    
    return ret;

}

void my_bus_exit()
{
    bus_unregister(&my_bus_type);
}

 /*符號導(dǎo)出
  * Export a simple attribute.
 */
EXPORT_SYMBOL(my_bus_type);
module_init(my_bus_init);
module_exit(my_bus_exit);

  • 2.0 驅(qū)動device_driver定義剧腻,當加載驅(qū)動時候,會在總線上找到它能夠處理的設(shè)備灰伟。
    1. 1 驅(qū)動的注冊

int driver_register(struct device_driver *drv)

  • 2.2驅(qū)動的注銷

void driver_unregister(struct device_driver *drv)

在總線上掛載驅(qū)動:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jalyn Fang");

extern struct bus_type my_bus_type;

int my_probe(struct device *dev)
{
    printk("driver found the device it can handle!\n");
    return 0;
}

struct device_driver my_driver = {
    .name = "my_dev",
      /*指明這個驅(qū)動程序是屬于my_bus_type這條總線上的設(shè)備*/
    .bus = &my_bus_type,    
     /*在my_bus_type總線上找到它能夠處理的設(shè)備儒旬,
    就調(diào)用my_probe;刪除設(shè)備調(diào)用my_remove*/
    .probe = my_probe,
   /*能夠處理的設(shè)備? 
      1遏乔、什么時候驅(qū)動程序從總線找能夠處理的設(shè)備发笔;
      答:驅(qū)動注冊時候
      2凉翻、憑什么說能夠處理呢?(或者說標準是什么)前计;
      答:驅(qū)動與設(shè)備都是屬于總線上的垃杖,利用總線的
      結(jié)構(gòu)bus_type中match函數(shù)
   */
};

int my_driver_init()
{
    int ret;
    
    ret = driver_register(&my_driver);
    
    return ret;
}

void my_driver_exit()
{
    driver_unregister(&my_driver);  
}

module_init(my_driver_init);
module_exit(my_driver_exit);
  • 3.0
    1. 1 設(shè)備的注冊

int device_register(struct device *dev)

    1. 2 設(shè)備的注銷

void device_unregister(struct device *dev)

在總線上掛載設(shè)備:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");

extern struct bus_type my_bus_type;

struct device my_dev = {
     .init_name = "my_dev",
     .bus = &my_bus_type,   
     .release = my_dev_release,
};

int my_device_init()
{
    int ret;
     ret = device_register(&my_dev);
     return ret;
     
}


void my_device_exit()
{
    device_unregister(&my_dev);
}

module_init(my_device_init);
module_exit(my_device_exit);



參考:
https://blog.csdn.net/wh_19910525/article/details/7398051

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末调俘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子彩库,更是在濱河造成了極大的恐慌,老刑警劉巖宛渐,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件眯搭,死亡現(xiàn)場離奇詭異,居然都是意外死亡鳞仙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門幔荒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梳玫,“玉大人,你說我怎么就攤上這事姚垃∨渭桑” “怎么了掂墓?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵看成,是天一觀的道長。 經(jīng)常有香客問我川慌,道長,這世上最難降的妖魔是什么兑燥? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任琴拧,我火速辦了婚禮,結(jié)果婚禮上挣饥,老公的妹妹穿的比我還像新娘。我一直安慰自己亮靴,他們只是感情好于置,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搓侄,像睡著了一般话速。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泊交,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音云石,去河邊找鬼研乒。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的谣膳。 我是一名探鬼主播铅乡,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼隆判!你這毒婦竟也來了犬庇?” 一聲冷哼從身側(cè)響起侨嘀,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤咬腕,失蹤者是張志新(化名)和其女友劉穎葬荷,沒想到半個月后涨共,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宠漩,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡扒吁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了魁索。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盼铁。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饶火,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肤寝,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布瀑构,位于F島的核電站,受9級特大地震影響世吨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耘婚,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一陆赋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赖临,春花似錦、人聲如沸兢榨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兼雄。三九已至,卻和暖如春块攒,著一層夾襖步出監(jiān)牢的瞬間金砍,已是汗流浹背局蚀。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工琅绅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鹅巍,地道東北人千扶。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓澎羞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妆绞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,905評論 2 89
  • 很多人喜歡貓,不喜歡巫女图焰。 人們疑惑,貓為什么總跟著巫女技羔? 巫女也不知道,當初鳖粟,巫女自信滿滿地想召喚出一頭獅子,心...
    藥不方閱讀 467評論 0 1
  • 1.運動模型復(fù)盤: 本周堅持運動了6天:跑步3次牺弹,訓(xùn)練1次时呀,無氧運動2次晶默。其實我之前也在運動,只是大多時候偷懶了磺陡,...
    KAKA旭閱讀 184評論 0 0
  • 韶華不為少年留 時光從不停歇的流逝 總歸要為自己留著些回憶 所以決定要用文字記錄下一些事情 有關(guān)于每一次靈魂的相遇...
    肆酒似九閱讀 266評論 0 0