娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

IMX257 總線設(shè)備驅(qū)動模型編程之總線篇

發(fā)布者:BlissfulMoon最新更新時間:2024-08-15 來源: cnblogs關(guān)鍵字:總線設(shè)備 手機(jī)看文章 掃描二維碼
隨時隨地手機(jī)看文章

從現(xiàn)在開始,我們開始來實(shí)現(xiàn) 總線-設(shè)備-驅(qū)動模型中的總線。、

我們這個程序的目標(biāo)是在 sysfs文件系統(tǒng)的/sys/bus/ 目錄下面建立一個文件夾。

一、總線介紹

1. 總線數(shù)據(jù)結(jié)構(gòu)bus_type

struct bus_type 結(jié)構(gòu)體的定義如下:

struct bus_type {

const char *name; --總線名

struct bus_attribute *bus_attrs; --總線屬性

struct device_attribute *dev_attrs; --總線設(shè)備屬性

struct driver_attribute *drv_attrs; --總線驅(qū)動屬性

以下的函數(shù)會在設(shè)備注冊或驅(qū)動注冊的時候調(diào)用。

 

int (*match)(struct device *dev, struct device_driver *drv);

--實(shí)現(xiàn)設(shè)備與驅(qū)動的匹配。不同的總線實(shí)現(xiàn)匹配的方法不同,如platform總線采用name匹配,而usb_bus采用id匹配

 

int (*uevent)(struct device *dev, struct kobj_uevent_env *env);

int (*probe)(struct device *dev);

--在2.6的內(nèi)核中實(shí)現(xiàn)一個設(shè)備與驅(qū)動的探測。主要是因?yàn)?a href="http://www.nncyjs.com/zhuanti/90Oan1" style="color:#4595e6;" target="_blank">熱插拔的設(shè)備的增多。

 

int (*remove)(struct device *dev); --移除設(shè)備

void (*shutdown)(struct device *dev); --關(guān)閉設(shè)備

int (*suspend)(struct device *dev, pm_message_t state);

int (*suspend_late)(struct device *dev, pm_message_t state);

int (*resume_early)(struct device *dev);

int (*resume)(struct device *dev);

 

struct dev_pm_ops *pm; --電源管理

struct bus_type_private *p; --bus_type私有成員,

這個結(jié)構(gòu)體中主要包括了kset以及klist,用于管理其掛載其總線下的設(shè)備和驅(qū)動

};

 

下面我們來看看bus_type_private結(jié)構(gòu)體

struct bus_type_private {

struct kset subsys; /*代表該bus子系統(tǒng),里面的kobj是該bus的主kobj,最頂層*/

struct kset *drivers_kset; /* 掛接到該總線上所有的驅(qū)動的集合 */

struct kset *devices_kset; /* 掛接到該總線上所有的設(shè)備的集合 */

struct klist klist_devices; /* 總線上所有設(shè)備的的列表 */

struct klist klist_drivers; /* 總線上所有驅(qū)動的的列表 */

struct blocking_notifier_head bus_notifier;

unsigned int drivers_autoprobe:1; /*設(shè)置是否在注冊驅(qū)動時,自動探測(probe)設(shè)備*/

struct bus_type *bus; /*回指包含自己的總線*/

};

 

 

2. 注冊總線

內(nèi)核中采用bus_register來注冊一個新的總線。

其使用如:ret = bus_register(&my_bus_type);

bus_register函數(shù)的源碼如下(剔除一些錯誤處理):

int bus_register(struct bus_type *bus)

{

int retval;

struct bus_type_private *priv;

priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);

priv->bus = bus;

bus->p = priv;

BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);

retval = kobject_set_name(&priv->subsys.kobj, '%s', bus->name);

//設(shè)置kobject名稱,有時會使用snprintf來設(shè)置,不過會出現(xiàn)bug,最好使用該函數(shù)。

 

priv->subsys.kobj.kset = bus_kset; //kobj中的kset指向父kset

priv->subsys.kobj.ktype = &bus_ktype; //kobj中的ktype指向父ktype

priv->drivers_autoprobe = 1; //設(shè)置總線下的設(shè)備和驅(qū)動自動探測

retval = kset_register(&priv->subsys);

//注冊kset,關(guān)于kset,kobject,以及ktype的關(guān)系以后在學(xué)習(xí)

 

retval = bus_create_file(bus, &bus_attr_uevent); //創(chuàng)建bus的文件屬性

priv->devices_kset = kset_create_and_add('devices', NULL,&priv->subsys.kobj);

//在父kset下創(chuàng)建和加入名為devices和drivers的kset

 

priv->drivers_kset = kset_create_and_add('drivers', NULL,&priv->subsys.kobj);

klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);

//初始化klist,這個函數(shù)主要是實(shí)現(xiàn)一些賦值及初始化的功能

 

klist_init(&priv->klist_drivers, NULL, NULL);

retval = add_probe_files(bus);

//主要是創(chuàng)建該bus下probe的屬性文件,可以通過cat file 和cat x > file 向?qū)傩晕募x出和寫入數(shù)據(jù)。

 

retval = bus_add_attrs(bus); --添加bus自帶的屬性文件

return 0;

}

 

從上面的程序得知,總線注冊主要工作如下

創(chuàng)建bus_type_ private,并申請相應(yīng)的內(nèi)存,通過賦值bus_type的一些屬性,然后添加進(jìn)入list

下面函數(shù)其實(shí)是實(shí)現(xiàn)一個從鏈表的節(jié)點(diǎn),查詢到該節(jié)點(diǎn)所屬的設(shè)備,并且減少dev的計(jì)數(shù)。

static void klist_devices_get(struct klist_node *n)

{

struct device *dev = container_of(n, struct device, knode_bus);

get_device(dev);

}

 

其實(shí)bus的注冊比較簡單,說到底還是kset和kobject控制著這一切,拋開kset和kobject的具體實(shí)現(xiàn),bus還是很好理解的。

 

3. 創(chuàng)建屬性文件

 

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);

通過BUS_ATTR宏定義定義一個屬性文件,其參數(shù)依次是屬性文件名,屬性文件的mode,顯示屬性文件函數(shù)和存儲屬性文件函數(shù)。

顯示屬性文件的函數(shù)如下所示:

static ssize_t show_bus_version(struct bus_type *bus, char *buf){

return snprintf(buf, PAGE_SIZE, '%sn', Version);

}

 

創(chuàng)建屬性文件:

bus_create_file(&my_bus_type, &bus_attr_version)

其實(shí)原理上,它就是調(diào)用sysfs_create_file函數(shù)來實(shí)現(xiàn)的。

 

4. bus的注銷

bus的卸載函數(shù)如下所示:

bus_unregister(&my_bus_type);

 

二、總線實(shí)例介紹

1. 定義bus_type結(jié)構(gòu)體

 

以及實(shí)現(xiàn).match的my_match函數(shù),用于檢測驅(qū)動與設(shè)備是否匹配

2. 定義bus屬性文件結(jié)構(gòu)體

上面的version是我們前面定義的一個字符串

 

3. 在init函數(shù)中注冊總線

如圖所示,

bus_register(&my_bus_type); 用于注冊我們的總線,加入總線列表list,具體功能看前面

bus_create_file(&my_bus_type, &bus_attr_version); 創(chuàng)建我們my_bus_type 的屬性文件

&bus_attr_version 這個結(jié)構(gòu)體就是前面我們

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL); 得到的。

查看linux源碼如下:

 

4. 在exit函數(shù)中卸載總線

 

至止,我們已經(jīng)實(shí)現(xiàn)了 總線-驅(qū)動-設(shè)備 模型中的總線了

5. 編譯測試

 

附上源代碼


 1 #include

 2 #include

 3 #include

 4 #include

 5 #include

 6 

 7 static char *Version = '$LoverXueEr : 1.0 $';

 8 

 9 //檢測驅(qū)動是否匹配設(shè)備,dev->bus_id 和 driver->name相等的

10 static int my_match(struct device *dev ,struct device_driver *driver){

11     return !strncmp(dev_name(dev),driver->name,strlen(driver->name));

12 }

13 

14 struct bus_type my_bus_type = {

15     .name = 'my_bus',

16     .match = my_match,

17 };

18 //顯示總線版本號

19 static ssize_t show_bus_version(struct bus_type *bus,char *buf){

20     return snprintf(buf,PAGE_SIZE,'%sn',Version);

21 }

22 

23 //產(chǎn)生后面的 bus_attr_version 結(jié)構(gòu)體

24 static BUS_ATTR(version,S_IRUGO, show_bus_version, NULL);

25 

26 static int __init my_bus_init(void){

27     int ret;

28     /* 注冊總線 */

29     ret = bus_register(&my_bus_type);

30     if(ret)

31         return ret;

32     /*  創(chuàng)建屬性文件 */

33     if(bus_create_file(&my_bus_type, &bus_attr_version))

34         printk('<0>Fail to create version attribute! n');

35     return ret;

36 }

37 

38 static void my_bus_exit(void){

39     bus_unregister(&my_bus_type);

40 }

41 

42 module_init(my_bus_init);

43 module_exit(my_bus_exit);

44 

45 

46 MODULE_AUTHOR('Lover雪兒');

47 MODULE_LICENSE('GPL');


關(guān)鍵字:總線設(shè)備 引用地址:IMX257 總線設(shè)備驅(qū)動模型編程之總線篇

上一篇:IMX257 總線設(shè)備驅(qū)動模型編程之總線篇(二)
下一篇:IMX257設(shè)備驅(qū)動模型之Kset

推薦閱讀最新更新時間:2025-06-07 23:40

基于CPCI總線的便攜式電磁閥測試設(shè)備設(shè)計(jì)
  1.?前言   由于某型號電磁閥熱真空試驗(yàn)需要出廠完成,在試驗(yàn)過程中需測試閥門響應(yīng)特性,傳統(tǒng)的測試設(shè)備體積無法滿足運(yùn)輸需求,因此需要配備便于攜帶的電磁閥測試設(shè)備。   CompactPCI簡稱CPCI,中文又稱緊湊型PCI,是國際PICMG協(xié)會于1994提出來的一種總線接口標(biāo)準(zhǔn)。它將VME密集堅(jiān)固的封裝和大型設(shè)備的極佳冷卻效果以及PC廉價、易采用最新處理能力的芯片結(jié)合在一起,既保證了99.999%的高可靠度,又極大降低了硬件和軟件開發(fā)成本。其整體機(jī)構(gòu)緊湊,安裝牢固,適應(yīng)各種運(yùn)輸條件,可靠性高。各功能板采用CPCI總線的模塊化結(jié)構(gòu),插拔十分安全方便,特別適合本系統(tǒng)的多種型號測試對象和多種測試工況的要求。   2.
[嵌入式]
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 盐边县| 新源县| 航空| 安乡县| 滕州市| 黎城县| 金寨县| 香格里拉县| 叙永县| 乐山市| 页游| 石柱| 丰镇市| 葫芦岛市| 天台县| 禹城市| 耿马| 女性| 呼图壁县| 清徐县| 高阳县| 博野县| 华亭县| 军事| 麦盖提县| 新源县| 华容县| 章丘市| 讷河市| 房产| 中江县| 丽水市| 囊谦县| 富民县| 南阳市| 如皋市| 育儿| 红安县| 余姚市| 阿瓦提县| 新兴县|