亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1506 | 回復(fù): 0
打印 上一主題 下一主題

linux設(shè)備驅(qū)動(dòng)歸納總結(jié)(八)3設(shè)備模型的分層與面向?qū)ο?/a> [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-02-03 14:56 |只看該作者 |倒序?yàn)g覽

linux設(shè)備驅(qū)動(dòng)歸納總結(jié)(八):3.設(shè)備管理的分層與面向?qū)ο笏枷?/FONT>


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

前面的內(nèi)容介紹了總線、設(shè)備和驅(qū)動(dòng)函數(shù)的關(guān)系和操作。從這節(jié)開始,介紹設(shè)備管理中的分層思想和面向?qū)ο笏枷耄质俏易约合咕幍,《LDD》上指的是結(jié)構(gòu)體內(nèi)嵌)?梢岳斫馐瞧脚_(tái)類設(shè)備(platform)的一個(gè)過度。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


一、設(shè)備管理的分層


回想一下之前的設(shè)備和驅(qū)動(dòng)函數(shù)注冊(cè)時(shí),它們是自己指定所屬的總線。但是,內(nèi)核開發(fā)人員覺得,這樣的方法不好,應(yīng)該由總線來提供設(shè)備和驅(qū)動(dòng)的注冊(cè)函數(shù)。當(dāng)設(shè)備和驅(qū)動(dòng)需要注冊(cè)到指定總線時(shí),那就必須使用該總線為設(shè)備和驅(qū)動(dòng)提供的注冊(cè)函數(shù)。


所以,將上一節(jié)的bus.c修改如下:

/*8th_devModule_3/1st/bus.c*/

21 /*總線提供的設(shè)備注冊(cè)函數(shù)*/

22 int usb_device_register(struct device *dev)

23 {

24     dev->bus = &usb_bus; //設(shè)備device的總線為usb_bus

25     return device_register(dev); //注冊(cè)此device

26 }

27 void usb_device_unregister(struct device *dev)

28 {

29     device_unregister(dev);

30 }

31 EXPORT_SYMBOL(usb_device_register);

32 EXPORT_SYMBOL(usb_device_unregister);

33 /*總線提供的驅(qū)動(dòng)注冊(cè)函數(shù)*/

34 int usb_driver_register(struct device_driver *drv)

35 {

36     drv->bus = &usb_bus; //設(shè)置driver的總線為usb_bus

37     return driver_register(drv); //注冊(cè)此driver

38 }

39 void usb_driver_unregister(struct device_driver *drv)

40 {

41     driver_unregister(drv);

42 }

43 EXPORT_SYMBOL(usb_driver_register);

44 EXPORT_SYMBOL(usb_driver_unregister);

再寫一個(gè)bus.h,讓設(shè)備和驅(qū)動(dòng)函數(shù)包含該頭文件后能夠使用總線提供的驅(qū)動(dòng)函數(shù)。

/*8th_devModule_3/1st/bus.h*/

1 #ifndef _BUS_H

2 #define _BUS_H

3

4 int usb_device_register(struct device *dev);

5 void usb_device_unregister(struct device *dev);

6

7 int usb_driver_register(struct device_driver *drv);

8 void usb_driver_unregister(struct device_driver *drv);

9 #endif /* _BUS_H */

上面的程序可以看到,其實(shí)也沒干什么事情,只是由總線來封裝并且向設(shè)備和驅(qū)動(dòng)函數(shù)提供注冊(cè)函數(shù),便于管理。而不像以前,設(shè)備和驅(qū)動(dòng)只要知道總線的名字,就能注冊(cè)到指定的總線中。

再修改一下設(shè)備和驅(qū)動(dòng)函數(shù)的代碼:

/*8th_devModule_3/1st/device.c*/

11 /*結(jié)構(gòu)體中不需要指定總線的成員,交由usb_device_register來完成*/

12 struct device usb_device = {

13     .bus_id = "usb_mouse",

14     .release = usb_dev_release, //必須要都有release函數(shù),不然卸載時(shí)會(huì)出錯(cuò)

15 };

16

17 static int __init usb_device_init(void)

18 {

19     int ret;

20

21     ret = usb_device_register(&usb_device);

22     if(ret){

23     printk("device register failed!\n");

24     return ret;

25     }

26

27     printk("usb device init\n");

28     return 0;

29 }

30

31 static void __exit usb_device_exit(void)

32 {

33     usb_device_unregister(&usb_device);

34     printk("usb device bye!\n");

35 }


/*8th_devModule_3/1st/driver.c*/

24 /*結(jié)構(gòu)體中不需要指定總線的成員,交由usb_device_register來完成*/

25 struct device_driver usb_driver = {

26     .name = "usb_mouse", ///sys/中的驅(qū)動(dòng)目錄名字

27     .probe = usb_driver_probe,

28     .remove = usb_driver_remove,

29 };

30

31 static int __init usb_driver_init(void)

32 {

33     int ret;

34     /*驅(qū)動(dòng)注冊(cè),注冊(cè)成功后在/sys/bus/usb/driver目錄下創(chuàng)建目錄usb_mouse*/

35     ret = usb_driver_register(&usb_driver);

36     if(ret){

37     printk("driver register failed!\n");

38     return ret;

39     }

40     printk("usb driver init\n");

41     return 0;

42 }

43

44 static void __exit usb_driver_exit(void)

45 {

46     usb_driver_unregister(&usb_driver);

47     printk("usb driver bye!\n");

48 }

修改完畢,驗(yàn)證一下,效果和之前的一樣,我也不詳細(xì)解釋:

[root: 1st]# insmod bus.ko

usb bus init

[root: 1st]# insmod device.ko

usb device init

[root: 1st]# insmod driver.ko

match success

match success

init usb mouse

usb driver init

[root: 1st]# rmmod device

remove mouse driver

<kernel> release

usb device bye!

[root: 1st]# rmmod driver

usb driver bye!

[root: 1st]# rmmod bus

usb bus bye!


二、面向?qū)ο笏枷搿Y(jié)構(gòu)內(nèi)嵌


device結(jié)構(gòu)體分別包含了設(shè)備模型的基本信息。然后,大多數(shù)的子系統(tǒng)還會(huì)記錄該結(jié)構(gòu)體以外但與設(shè)備相關(guān)的信息。因此,單純用一個(gè)device結(jié)構(gòu)來表示設(shè)備是很少見的,而是把device結(jié)構(gòu)體內(nèi)嵌到其他的結(jié)構(gòu)體中。當(dāng)然,device_driver也是一樣。


接下來,我封裝一下設(shè)備和驅(qū)動(dòng)函數(shù)的結(jié)構(gòu)體:

/*8th_devModule_3/2nd/bus.h*/

4 struct usb_device{ //usb_device中包含device結(jié)構(gòu)體

5     unsigned long phys, virt; //存放設(shè)備和物理地址和對(duì)應(yīng)的虛擬地址

6     int irq; //存放設(shè)備的中斷號(hào)

7     int VendorID, DeviceID; //存放設(shè)備的生產(chǎn)廠商編號(hào)和設(shè)備編號(hào)

8

9     struct device dev;

10 };

11

12 struct usb_driver{ //usb_driver中包含device_driver結(jié)構(gòu)體

13     int VendorID, DeviceID;

14

15     struct device_driver drv;

16 };

17

18 int usb_device_register(struct usb_device *usb_dev);

19 void usb_device_unregister(struct usb_device *usb_dev);

20

21 int usb_driver_register(struct usb_driver *usb_drv);

22 void usb_driver_unregister(struct usb_driver *usb_drv);

23 #endif /* _BUS_H */

在上面,我將設(shè)備結(jié)構(gòu)體device內(nèi)嵌到usb_device結(jié)構(gòu)體中,該結(jié)構(gòu)體中還有成員生產(chǎn)廠商編號(hào)和設(shè)備編號(hào),在match函數(shù)會(huì)用來配對(duì),成員irqphysvirt在接下來的章節(jié)會(huì)用到。

同樣的,驅(qū)動(dòng)函數(shù)結(jié)構(gòu)體device_driver被內(nèi)嵌到usb_driver結(jié)構(gòu)體中,該結(jié)構(gòu)體中還有成員生產(chǎn)廠商編號(hào)和設(shè)備編號(hào),在match函數(shù)中會(huì)用來匹配。


因?yàn)槲叶x了新的結(jié)構(gòu)體,三個(gè)函數(shù)都的傳參都有了稍稍的改變。


首先是bus.c

/*8th_devModule_3/2nd/bus.c*/

7 int usb_bus_match(struct device *dev, struct device_driver *drv)

8 { /*使用container_of找出總線自己定義的結(jié)構(gòu)體*/

9       struct usb_device *usb_dev = container_of(dev, struct usb_device, dev);

10     struct usb_driver *usb_drv = container_of(drv, struct usb_driver, drv);

11     /*配對(duì)函數(shù)判斷驅(qū)動(dòng)和設(shè)備的生產(chǎn)廠商編號(hào)和設(shè)備編號(hào)是否一致*/

12     if((usb_dev->VendorID == usb_drv->VendorID) &&

13                 (usb_dev->DeviceID == usb_drv->DeviceID)){

14         printk("match success\n");

15         return 1;

16     }else{

17         printk("match failed\n");

18         return 0;

19     }

20 }

bus.c中的配對(duì)函數(shù)被我修改了兩部分:

1、通過container_of來獲得usb_deviceusb_driver結(jié)構(gòu)體。

2、修改了配對(duì)了方法,通過判斷兩者生產(chǎn)廠商編號(hào)與設(shè)備號(hào)是否都一致。


因?yàn)槎x了新的結(jié)構(gòu)體,所以我將注冊(cè)函數(shù)的參數(shù)也修改了。

/*8th_devModule_3/2nd/bus.c*/

26 /*總線提供的設(shè)備注冊(cè)函數(shù)*/

27 int usb_device_register(struct usb_device *usb_dev)

28 {

29     usb_dev->dev.bus = &usb_bus; //設(shè)備device的總線為usb_bus

30     return device_register(&usb_dev->dev); //注冊(cè)此device

31 }

32 void usb_device_unregister(struct usb_device *usb_dev)

33 {

34     device_unregister(&usb_dev->dev);

35 }

36 EXPORT_SYMBOL(usb_device_register);

37 EXPORT_SYMBOL(usb_device_unregister);

38 /*總線提供的驅(qū)動(dòng)注冊(cè)函數(shù)*/

39 int usb_driver_register(struct usb_driver *usb_drv)

40 {

41     usb_drv->drv.bus = &usb_bus; //設(shè)置driver的總線為usb_bus

42     return driver_register(&usb_drv->drv); //注冊(cè)此driver

43 }

44 void usb_driver_unregister(struct usb_driver *usb_drv)

45 {

46     driver_unregister(&usb_drv->drv);

47 }

48 EXPORT_SYMBOL(usb_driver_register);

49 EXPORT_SYMBOL(usb_driver_unregister);


接著是device.c

/*8th_evModule_3/2nd/device.c*/

12 struct usb_device mouse_dev = {

13     .VendorID = 0x1122,

14     .DeviceID = 0x3344,

15     .dev = {

16         .bus_id = "usb_mouse",

17         .release = usb_dev_release,

18     },

19 };

20

21 static int __init usb_device_init(void)

22 {

23     int ret;

24

25     ret = usb_device_register(&mouse_dev);

26     if(ret){

27         printk("device register failed!\n");

28         return ret;

29     }

30

31     printk("usb device init\n");

32     return 0;

33 }

34

35 static void __exit usb_device_exit(void)

36 {

37     usb_device_unregister(&mouse_dev);

38     printk("usb device bye!\n");

39 }


最后再看看driver.c

/*8th_devModule_3/2nd/driver.c*/

25 struct usb_driver mouse_drv = {

26     .VendorID = 0x1122,

27     .DeviceID = 0x3344,

28     .drv = {

29         .name = "usb_mouse", ///sys/中的驅(qū)動(dòng)目錄名字

30         .probe = usb_driver_probe,

31         .remove = usb_driver_remove,

32     },

33 };

34

35 static int __init usb_driver_init(void)

36 {

37     int ret;

38     /*驅(qū)動(dòng)注冊(cè),注冊(cè)成功后在/sys/bus/usb/driver目錄下創(chuàng)建目錄usb_mouse*/

39     ret = usb_driver_register(&mouse_drv);

40     if(ret){

41         printk("driver register failed!\n");

42         return ret;

43     }

44     printk("usb driver init\n");

45     return 0;

46 }

47

48 static void __exit usb_driver_exit(void)

49 {

50     usb_driver_unregister(&mouse_drv);

51     printk("usb driver bye!\n");

52 }


修改完畢,看看效果,其實(shí)就是和之前一模一樣。

[root: /]# cd review_driver/8th_devModule/8th_devModule_3/2nd/

[root: 2nd]# insmod bus.ko

usb bus init

[root: 2nd]# insmod device.ko

usb device init

[root: 2nd]# insmod driver.ko

match success

match success

init usb mouse

usb driver init

[root: 2nd]# rmmod device

remove mouse driver

<kernel> release

usb device bye!

[root: 2nd]# rmmod driver

usb driver bye!

[root: 2nd]# rmmod bus

usb bus bye!


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


三、總結(jié)


這節(jié)內(nèi)容并不多,其實(shí)就是修改修改一下原來的代碼,等到我介紹平臺(tái)類設(shè)備的時(shí)候你就會(huì)發(fā)現(xiàn),其實(shí)平臺(tái)類就是這樣一步步封裝起來的(當(dāng)然比我的復(fù)雜)。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

源代碼: 8th_devModule_3.rar  

您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP