版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、總線設(shè)備驅(qū)動(dòng)模型主要包含總線、設(shè)備、驅(qū)動(dòng)三個(gè)部分,總線可以是一條真實(shí)存在的總 線,例如USB、I2C等典型的設(shè)備。但是對(duì)于一些設(shè)備(內(nèi)部的設(shè)備)可能沒(méi)有現(xiàn)成的總線。 Linux 2.6內(nèi)核中引入了總線設(shè)備驅(qū)動(dòng)模型??偩€設(shè)備驅(qū)動(dòng)模型與之前的三類驅(qū)動(dòng)(字符、塊 設(shè)備、網(wǎng)絡(luò)設(shè)備)沒(méi)有必然的聯(lián)系。設(shè)備只是搭載到了總線中。在linux內(nèi)核中假設(shè)存在一 條虛擬總線,稱之為platform總線。platform總線相比與常規(guī)的總線模型其優(yōu)勢(shì)主要是 platform總線是由內(nèi)核實(shí)現(xiàn)的,而不用自己定義總線類型,總線設(shè)備來(lái)加載總線。platform 總線是內(nèi)核已經(jīng)實(shí)現(xiàn)好的。只需要添加相應(yīng)的platform dev
2、ice和platform driver。具體的實(shí) 現(xiàn)過(guò)程主要包括如下的過(guò)程:兩者的工作順序是先定義platform_device -注冊(cè)platform_device-,再定義 platform_driver- 注冊(cè) platform_driver。整體而言只需要完成兩個(gè)步驟,也就是設(shè)備的實(shí)現(xiàn)和驅(qū)動(dòng)的實(shí)現(xiàn),每一個(gè)實(shí)現(xiàn)都包括相 關(guān)結(jié)構(gòu)體的定義和注冊(cè)。platform_device 注冊(cè)需要注意的是platform_device實(shí)質(zhì)上是經(jīng)過(guò)處理過(guò)的設(shè)備,在platform_device結(jié)構(gòu)體 中存在一個(gè)設(shè)備結(jié)構(gòu)體,與之前的設(shè)備存在差別的是引入了設(shè)備資源。這些設(shè)備資源就能實(shí) 現(xiàn)對(duì)設(shè)備寄存器,中斷等資
3、源的訪問(wèn)。平臺(tái)設(shè)備的基本結(jié)構(gòu)體如下: struct platform_device /*設(shè)備名*/const char * name;/*設(shè)備ID號(hào)*/int id;/*結(jié)構(gòu)體包含一個(gè)具體的device結(jié)構(gòu)體*/struct device dev;/*資源的數(shù)量*/u32num_resources;/*資源結(jié)構(gòu)體,用來(lái)保存硬件的資源*/struct resource * resource;/*平臺(tái)設(shè)備的ID*/struct platform_device_id *id_entry;其中struct device和struct resource是重要的結(jié)構(gòu)體。struct device在總線設(shè)備
4、驅(qū)動(dòng)模型中 已經(jīng)提到了。這次討論一下struct resource0 struct resource /*資源的起始值,如果是地址,那么是物理地址,不是虛擬地址*/resource_size_t start;/*資源的結(jié)束值,如果是地址,那么是物理地址,不是虛擬地址7resource_size_t end;/*資源名*/const char *name;/*資源的標(biāo)示,用來(lái)識(shí)別不同的資源*/unsigned long flags;/*資源指針,可以構(gòu)成鏈表*/struct resource *parent, *sibling, *child; platform_device的注冊(cè)很簡(jiǎn)單,只需要
5、在設(shè)備的初始化函數(shù)中首先定義相應(yīng)的設(shè)備,通常 采用函數(shù) platform_device *platform_device_alloc(const char *name, int id)動(dòng)態(tài)申請(qǐng),通常 name就是需要申請(qǐng)的設(shè)備名,而id為-1。然后采用int platform_device_add(struct platform_device *pdev)或者int platform_device_register(struct platform_device *pdev)注冊(cè)定義好的設(shè)備即可。同樣在退出函數(shù)中釋放注冊(cè)好的設(shè)備即可,可以采用函數(shù):void platform_device_unr
6、egister(struct platform_device *pdev。然后一個(gè)平臺(tái)設(shè)備就完成了,不需要像自己實(shí)現(xiàn)模型時(shí)定義相關(guān)的文件屬性等。設(shè)備資源可以通過(guò)相關(guān)函數(shù)得到:struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num)中斷資源也可以通過(guò):int platform_get_irq(struct platform_device *dev, unsigned int num)資源的使用主要是驅(qū)動(dòng)實(shí)現(xiàn)過(guò)程中需要使用到的,但是后期的使用一般需要
7、在驅(qū)動(dòng)的probe 函數(shù)中實(shí)現(xiàn)申請(qǐng)中斷或者IO內(nèi)存才能使用,而不能直接使用。特別是資源中的地址通常是 物理地址,需要通過(guò)申請(qǐng)IO內(nèi)存和映射完成物理到虛擬地址的轉(zhuǎn)換,便于進(jìn)程的訪問(wèn)。platform_driver 注冊(cè)平臺(tái)驅(qū)動(dòng)結(jié)構(gòu)體platform_driver實(shí)現(xiàn)如下:struct platform_driver /*平臺(tái)驅(qū)動(dòng)需要實(shí)現(xiàn)的相關(guān)函數(shù)操作,其中的前4個(gè)函數(shù)與最后一個(gè)函數(shù)與device_driver中的函數(shù)是相同的本質(zhì)是實(shí)現(xiàn)對(duì)device_driver中相關(guān)函數(shù)的賦值。*/int (*probe)(struct platform_device *);int (*remove)(stru
8、ct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*suspend_late)(struct platform_device *, pm_message_t state);int (*resume_early)(struct platform_device *);int (*resume)(struct platform_device *);/*內(nèi)嵌了一個(gè)設(shè)備驅(qū)動(dòng)結(jié)構(gòu)體*/struct
9、 device_driver driver;/*平臺(tái)設(shè)備 ID,這與 platform_device 中的 struct platform_device_id *id_entry 是相同的主要是完成總線的匹配操作,platform總線的匹配操作第一匹配要素就是該元素。而 不再是簡(jiǎn)單的name選項(xiàng)。*/struct platform_device_id *id_table;通常驅(qū)動(dòng)的入口函數(shù):int (*probe)(struct platform_device *);當(dāng)總線完成了設(shè)備的match操作以后就會(huì)進(jìn)入驅(qū)動(dòng)中該函數(shù)的運(yùn)行。總線函數(shù)的匹配操作如下:static int platform_
10、match(struct device *dev, struct device_driver *drv)/*得到平臺(tái)設(shè)備的指針*/struct platform_device *pdev = to_platform_device(dev);/*得到平臺(tái)驅(qū)動(dòng)指針*/struct platform_driver *pdrv = to_platform_driver(drv);/* match against the id table first */*從定義上分析,id_table是首先匹配的對(duì)象,然后才是name的匹配,當(dāng)ID匹配完成 時(shí)就說(shuō)明匹配好了*/if (pdrv-id_table)re
11、turn platform_match_id(pdrv-id_table, pdev) != NULL;/* fall-back to driver name match */return (strcmp(pdev-name, drv-name) = 0);從上面的定義可以知道platform總線的匹配函數(shù)手下是比較id_table是匹配的首選項(xiàng)。probe函數(shù)稱之為探針函數(shù),用于檢測(cè)總線上有該驅(qū)動(dòng)能夠處理的設(shè)備,而remove函數(shù)則 是為了說(shuō)明總線上該驅(qū)動(dòng)能夠處理的設(shè)備被移除。因此這兩個(gè)函數(shù)是在平臺(tái)設(shè)備中一定要被實(shí)現(xiàn)的函數(shù)。其他的函數(shù)則不一樣要求實(shí)現(xiàn)。平臺(tái)驅(qū)動(dòng)的設(shè)計(jì)主要是完成平臺(tái)驅(qū)動(dòng)結(jié)構(gòu)體的
12、填充和注冊(cè)。通常的平臺(tái)驅(qū)動(dòng)結(jié)構(gòu)體實(shí)現(xiàn)如下:static struct platform_driver my_driver =/*平臺(tái)驅(qū)動(dòng)的probe函數(shù)實(shí)現(xiàn)*/.probe = my_probe,/*平臺(tái)驅(qū)動(dòng)的remove函數(shù)實(shí)現(xiàn)*/.remove = my_remove,/*實(shí)現(xiàn)設(shè)備驅(qū)動(dòng)的name和owner變量*/.driver =/*該參數(shù)主要實(shí)現(xiàn)總線中的匹配函數(shù)調(diào)用*/.name = my_dev,/*該函數(shù)表示模塊的擁有者*/.owner = THIS_MODULE,;其中的 my_probe和 my_remove是自己定義的probe和remove函數(shù)。最主要的是內(nèi)嵌設(shè)備驅(qū)動(dòng)結(jié)構(gòu)體
13、的填充,主要的填充包括name和owner兩個(gè),當(dāng)然也可以 包括其他的。由于沒(méi)有填充id_table,那么name就是總線匹配操作的第一選擇。因此如果沒(méi) 有填充好id_table,那么name元素是一定要實(shí)現(xiàn)的,不然不能完成相應(yīng)的設(shè)備驅(qū)動(dòng)匹配操作。完成platform_driver結(jié)構(gòu)體的填充過(guò)后就是完成驅(qū)動(dòng)的在初始化階段的注冊(cè)以及退出階段 的釋放操作,基本的實(shí)現(xiàn)函數(shù)為:注冊(cè)函數(shù),通常在驅(qū)動(dòng)初始化函數(shù)中調(diào)用:int platform_driver_register(struct platform_driver *drv)釋放函數(shù),通常在驅(qū)動(dòng)退出函數(shù)調(diào)用:void platform_driver
14、_unregister(struct platform_driver *drv)完成相關(guān)的注冊(cè)以后總線、設(shè)備、驅(qū)動(dòng)的大概框架就完成啦。但是這只是常用的框架,還不能在應(yīng)用程序中使用?;谄脚_(tái)驅(qū)動(dòng)的設(shè)備驅(qū)動(dòng)都是基于總線架構(gòu)的,基本的實(shí)現(xiàn)過(guò)程與之前的簡(jiǎn)單字符設(shè)備存在 較大的差別,主要的區(qū)別在驅(qū)動(dòng)的初始化不在是平臺(tái)設(shè)備驅(qū)動(dòng)的初始化函數(shù)中實(shí)現(xiàn),而是在 probe函數(shù)中實(shí)現(xiàn)。而驅(qū)動(dòng)的卸載函數(shù)則是在remove函數(shù)中實(shí)現(xiàn)。probe函數(shù)是平臺(tái)總線實(shí) 現(xiàn)匹配以后首先被調(diào)用的函數(shù),因此在其中實(shí)現(xiàn)字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)的初始化 是有意義的,這樣的設(shè)備驅(qū)動(dòng)就是基于平臺(tái)總線的設(shè)備驅(qū)動(dòng),便于維護(hù)。平臺(tái)總線驅(qū)動(dòng)的
15、注冊(cè)過(guò)程分析:int platform_driver_register(struct platform_driver *drv)/*第一步,仍然是完成結(jié)構(gòu)體的填充操作*/*驅(qū)動(dòng)的總線類型*/drv-driver.bus = &platform_bus_type;/*將自己定義的probe函數(shù)賦值給平臺(tái)驅(qū)動(dòng)中設(shè)備驅(qū)動(dòng)的probe函數(shù),其他函數(shù)類似*/if (drv-probe)drv-be = platform_drv_probe;if (drv-remove)drv-driver.remove = platform_drv_remove;if (drv-shutdown)drv-driver.
16、shutdown = platform_drv_shutdown;if (drv-suspend)drv-driver.suspend = platform_drv_suspend;if (drv-resume)drv-driver.resume = platform_drv_resume;/*第二步,仍然是完成一般設(shè)備驅(qū)動(dòng)的注冊(cè)操作*/*然手就是一般驅(qū)動(dòng)的注冊(cè),這樣就完成了設(shè)備的注冊(cè)*/return driver_register(&drv-driver);/*設(shè)備驅(qū)動(dòng)的probe函數(shù)的賦值過(guò)程*/static int platform_drv_probe(struct device *_d
17、ev)/*得到設(shè)備對(duì)應(yīng)的平臺(tái)驅(qū)動(dòng)*/struct platform_driver *drv = to_platform_driver(_dev-driver);/*得到設(shè)備的平臺(tái)設(shè)備*/struct platform_device *dev = to_platform_device(_dev);/*下面的probe是自己實(shí)現(xiàn)的probe函數(shù)。具體的實(shí)現(xiàn)思路:根據(jù)一般設(shè)備找對(duì)應(yīng)的平臺(tái)設(shè)備,同時(shí)根據(jù)設(shè)備的驅(qū)動(dòng)找到平臺(tái)驅(qū)動(dòng)。然后返回平臺(tái)驅(qū)動(dòng)的probe函數(shù)(自己實(shí)現(xiàn)通常是初始化操作)地址。*/return drv-probe(dev);實(shí)現(xiàn)的總線平臺(tái)驅(qū)動(dòng)模型的最簡(jiǎn)單源碼:平臺(tái)設(shè)備的實(shí)現(xiàn):device
18、.c#include#include#include#include#include#include/*平臺(tái)模型驅(qū)動(dòng)的平臺(tái)設(shè)備對(duì)象*/static struct platform_device *my_device;/*初始化函數(shù)*/static int _init my_device_init(void)int ret = 0;/*采用 platform_device_alloc 分配一個(gè) platform_device 對(duì)象 參數(shù)分別為 platform_device 的 name,和 id。*/my_device = platform_device_alloc(my_dev,-1);/*
19、注冊(cè)設(shè)備,注意不是platform_device_register,將平臺(tái)設(shè)備注冊(cè)到內(nèi)核中*/ ret = platform_device_add(my_device);/*如果出錯(cuò)釋放相關(guān)的內(nèi)存單元*/if(ret)platform_device_put(my_device);return ret;/*卸載處理函數(shù)*/static void _exit my_device_exit(void)platform_device_unregister(my_device);module_init(my_device_init);module_exit(my_device_exit);MODULE_
20、LICENSE(GPL);MODULE_AUTHOR(GP-);平臺(tái)驅(qū)動(dòng)的實(shí)現(xiàn):driver.c#include#include#include#include#include/*平臺(tái)驅(qū)動(dòng)中的probe和remove函數(shù)是必須實(shí)現(xiàn)的函數(shù)*/*設(shè)備驅(qū)動(dòng)的探測(cè)函數(shù),主要實(shí)現(xiàn)檢測(cè)總線上是否有該驅(qū)動(dòng)對(duì)應(yīng)的設(shè)備*/static my_probe(struct device *dev)/*如果添加實(shí)際的設(shè)備到該平臺(tái)總線設(shè)備驅(qū)動(dòng)模型中,則可以在該函數(shù) 中實(shí)現(xiàn)具體的設(shè)備驅(qū)動(dòng)函數(shù)的初始化操作,包括設(shè)備號(hào)的申請(qǐng),設(shè)備 的初始化,添加。自動(dòng)設(shè)備文件創(chuàng)建函數(shù)的添加等操作?;蛘呤腔祀s字符設(shè)備的相關(guān)初始化操作。當(dāng)然結(jié)構(gòu)體
21、的相關(guān)處理仍 然采取全局變量的形式。*/printk(Driver found devices which this driver can be handlen);return 0;/*設(shè)備驅(qū)動(dòng)的移除函數(shù),主要檢測(cè)該驅(qū)動(dòng)支持設(shè)備的移除活動(dòng)檢測(cè)*/static my_remove(struct device *dev)/*如果添加實(shí)際的設(shè)備到該平臺(tái)總線設(shè)備驅(qū)動(dòng)模型中,則可以在該函數(shù) 中實(shí)現(xiàn)具體的設(shè)備的釋放,包括設(shè)備的刪除,設(shè)備號(hào)的注銷(xiāo)等操作。*/printk(Driver found device unpludedn);return 0;static struct platform_driver
22、 my_driver =/*平臺(tái)驅(qū)動(dòng)的probe函數(shù)實(shí)現(xiàn)*/.probe = my_probe,/*平臺(tái)驅(qū)動(dòng)的remove函數(shù)實(shí)現(xiàn)*/.remove = my_remove,/*實(shí)現(xiàn)設(shè)備驅(qū)動(dòng)的name和owner變量*/.driver =/*該參數(shù)主要實(shí)現(xiàn)總線中的匹配函數(shù)調(diào)用*/.name = my_dev,/*該函數(shù)表示模塊的擁有者*/.owner = THIS_MODULE,;/*初始化函數(shù)*/static int _init my_driver_init(void)/*注冊(cè)平臺(tái)驅(qū)動(dòng)*/return platform_driver_register(&my_driver);/*退出函數(shù)*/
23、static void _exit my_driver_exit(void)/*注銷(xiāo)平臺(tái)驅(qū)動(dòng)*/return platform_driver_unregister(&my_driver);/*加載和卸載*/module_init(my_driver_init);module_exit(my_driver_exit);MODULE_LICENSE(GPL);MODULE_AUTHOR(GP-);將一般設(shè)備驅(qū)動(dòng)加入到總線設(shè)備模型中的相關(guān)操作是后期總結(jié)和學(xué)習(xí)的內(nèi)容。設(shè)備驅(qū)動(dòng)實(shí)現(xiàn) 的實(shí)現(xiàn)原理還是之前的那些操作,但是初始化和推出函數(shù)發(fā)生了改變??偨Y(jié):platform總線的驅(qū)動(dòng)模型只是在一般總線模型的基礎(chǔ)
24、上做了相關(guān)的延伸,實(shí)質(zhì)上只要 弄清除總線模型的一般原理,學(xué)習(xí)platform總線也就簡(jiǎn)單不少。但是畢竟還是學(xué)習(xí)階段。概述platform設(shè)備和驅(qū)動(dòng)與linux設(shè)備模型密切相關(guān)。platform在linux設(shè)備模型中,其實(shí)就 是一種虛擬總線沒(méi)有對(duì)應(yīng)的硬件結(jié)構(gòu)。它的主要作用就是管理系統(tǒng)的外設(shè)資源,比如io內(nèi) 存,中斷信號(hào)線。現(xiàn)在大多數(shù)處理器芯片都是soc,如s3c2440,它包括處理器內(nèi)核(arm920t) 和系統(tǒng)的外設(shè)(lcd接口,nandflash接口等)。linux在引入了 platform機(jī)制之后,內(nèi)核假 設(shè)所有的這些外設(shè)都掛載在platform虛擬總線上,以便進(jìn)行統(tǒng)一管理。platfor
25、m 總線1.在系統(tǒng)中platform對(duì)應(yīng)的文件drivers/base/platform.c,它不是作為一個(gè)模塊注冊(cè)到內(nèi) 核的,關(guān)鍵的注冊(cè)總線的函數(shù)由系統(tǒng)初始化部分,對(duì)應(yīng)/init/main.c中的do_basic_setup函 數(shù)間接調(diào)用。這里可以看出platform非常重要,要在系統(tǒng)其他驅(qū)動(dòng)加載之前注冊(cè)。下面分 析platform總線注冊(cè)函數(shù)cpp view plaincopyint _init platform_bus_init(void)int error;early_platform_cleanup();error = device_register(&platform_bus);/
26、總線也是設(shè)備,所以也要進(jìn)行設(shè)備的注冊(cè)if (error)return error;error = bus_register(&platform_bus_type);/注冊(cè) platform_bus_type 總線到內(nèi)核if (error)device_unregister(&platform_bus);return error;這個(gè)函數(shù)向內(nèi)核注冊(cè)了一種總線。他首先由/drivers/base/init.c中的driver_init函數(shù)調(diào)用, driver_init 函數(shù)由/init/main.c 中的 do_basic_setup 函數(shù)調(diào)用,do_basic_setup 這個(gè)函數(shù)由 kerne
27、l_init調(diào)用,所以platform總線是在內(nèi)核初始化的時(shí)候就注冊(cè)進(jìn)了內(nèi)核。2. platform_bus_type總線結(jié)構(gòu)與設(shè)備結(jié)構(gòu)(1)platform總線 設(shè)備結(jié)構(gòu)cpp view plaincopystruct device platform_bus = .init_name = platform,;platform總線也是一種設(shè)備,這里初始化一個(gè)device結(jié)構(gòu),設(shè)備名稱platform,因?yàn)闆](méi) 有指定父設(shè)備,所以注冊(cè)后將會(huì)在/sys/device/T出現(xiàn)platform目錄。(2) platform總線總線結(jié)構(gòu)cpp view plaincopystruct bus_type p
28、latform_bus_type = 2.name=platform,3.dev_attrs=platform_dev_attrs,4.match=platform_match,5.uevent=platform_uevent,6.pm=&platform_dev_pm_ops,7. ;platform_dev_attrs設(shè)備屬性platform_matchmatch函數(shù),這個(gè)函數(shù)在當(dāng)屬于platform的設(shè)備或者驅(qū)動(dòng)注冊(cè)到內(nèi)核時(shí)就會(huì)調(diào)用,完成設(shè)備與驅(qū)動(dòng)的匹配工作。platform_uevent熱插拔操作函數(shù)三.platform設(shè)備platform_device 結(jié)構(gòu)cpp view plai
29、ncopy1.struct platform_device 2.const char * name;3.intid;4.struct device dev;5.u32num_resources;6.struct resource * resource;7.struct platform_device_id *id_entry8./* arch specific additions */9.struct pdev_archdata archdata;10.;(1)platform_device結(jié)構(gòu)體中有一個(gè)struct resource結(jié)構(gòu),是設(shè)備占用系統(tǒng)的資源, 定義在ioport.h中,如下
30、cpp view plaincopystruct resource resource_size_t start;resource_size_t end;const char *name;unsigned long flags;struct resource *parent, *sibling, *child;(2) num_resources占用系統(tǒng)資源的數(shù)目,一般設(shè)備都占用兩種資源,io內(nèi)存和中斷 信號(hào)線。這個(gè)為兩種資源的總和。設(shè)備注冊(cè)函數(shù) platform_device_registercpp view plaincopyint platform_device_register(struc
31、t platform_device *pdev)device_initialize(&pdev-dev);return platform_device_add(pdev);這個(gè)函數(shù)首先初始化了 platform_device的device結(jié)構(gòu),然后調(diào)用platform_device_add, 這個(gè)是注冊(cè)函數(shù)的關(guān)鍵,下面分析platform_device_add:cpp view plaincopyint platform_device_add(struct platform_device *pdev)int i, ret = 0;4.if (!pdev)return -EINVAL;7.if
32、(!pdev-dev.parent)pdev-dev.parent = &platform_bus;/可以看出,platform設(shè)備的父設(shè)備一般都是platform_bus,所以注冊(cè)后的 platform 設(shè)備都出現(xiàn)在/sys/devices/platform_bus 下7.18.源4.35.pdev-dev.bus = &platform_bus_type;/掛到platform總線上if (pdev-id != -1)dev_set_name(&pdev-dev
33、, %s.%d, pdev-name, pdev-id);elsedev_set_name(&pdev-dev, %s, pdev-name);/設(shè)置設(shè)備名字,這個(gè)名字與/sys/devices/platform_bus下的名字對(duì)應(yīng) for (i = 0; i num_resources; i+) 下面操作設(shè)備所占用的系統(tǒng)資struct resource *p, *r = &pdev-resourcei;if (r-name = NULL)r-name = dev_name(&pdev-dev);p = r-parent;if (!p) if (resource_type(r) = IORES
34、OURCE_MEM) p = &iomem_resource;else if (resource_type(r) = IORESOURCE_IO) p = &ioport_resource;if (p & insert_resource(p, r) printk(KERN_ERR%s: failed to claim resource %dn, dev_name(&pdev-dev), i);9.40.ret = -EBUSY;goto failed;/上面主要是遍歷設(shè)備所占用的資源,找到對(duì)應(yīng)的父資源,如果沒(méi)有定義,那么根據(jù)資源的類型,分別賦予 iomem_resource
35、 和 ioport_resource,然后調(diào)用 insert_resource 插入 資源。這樣系統(tǒng)的資源就形成了一個(gè)樹(shù)形的數(shù)據(jù)結(jié)構(gòu),便于系統(tǒng)的管理pr_debug(Registering platform device %s. Parent at %sn,dev_name(&pdev-dev), dev_name(pdev-dev.parent);44.ret = device_add(&pdev-dev);/注冊(cè)到設(shè)備模型中if (ret = 0)return ret;failed:while (-i = 0) struct resource *r = &pdev-resourcei;un
36、signed long type = resource_type(r);if(type= IORESOURCE_MEM | type =IORESOURCE_IO)release_resource(r);returnret;mini2440內(nèi)核注冊(cè)platform設(shè)備過(guò)程因?yàn)橐环Nsoc確定之后,其外設(shè)模塊就已經(jīng)確定了,所以注冊(cè)platform設(shè)備就由板級(jí)初 始化代碼來(lái)完成,在mini2440中是mach-mini2440.c的mini2440_machine_init函數(shù)中調(diào) 用 platform_add_devices(mini2440_devices, ARRAY_SIZE(mini244
37、0_devices)來(lái)完成注 冊(cè)。這個(gè)函數(shù)完成mini2440的所有platform設(shè)備的注冊(cè):(1)platform_add_devices 函數(shù)是 platform_device_register 的簡(jiǎn)單封裝,它向內(nèi)核 注冊(cè)一組platform設(shè)備(2)mini2440_devices 是一個(gè) platform_device 指針數(shù)組,定義如下:cpp view plaincopystatic struct platform_device *mini2440_devices _initdata = &s3c_device_usb,&s3c_device_rtc,&s3c_device_lc
38、d,&s3c_device_wdt,&s3c_device_i2c0,&s3c_device_iis,&mini2440_device_eth,&s3c24xx_uda134x,&s3c_device_nand,&s3c_device_sdi,&s3c_device_usbgadget,;這個(gè)就是mini2440的所有外設(shè)資源了,每個(gè)外設(shè)的具體定義在/arch/arm/plat-s3c24xx/devs.c,下面以 s3c_device_lcd 為例說(shuō)明,其他的類似。 s3c_device_lcd 在 devs.c 中它定義為:cpp view plaincopystruct platform
39、_device s3c_device_lcd = .name= s3c2410-lcd,.id = -1,.num_resources= ARRAY_SIZE(s3c_lcd_resource),.resource= s3c_lcd_resource, TOC o 1-5 h z .dev= .dma_mask = &s3c_device_lcd_dmamask,.coherent_dma_mask = 0 xffffffffUL;可以看出,它占用的資源s3c_lcd_resource,定義如下:cpp view plaincopystatic struct resource s3c_lcd_
40、resource = 0 = .start=S3C24XX_PA_LCD,.end=S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,.flags=IORESOURCE_MEM, TOC o 1-5 h z ,1= .start=IRQ_LCD,.end=IRQ_LCD,.flags=IORESOURCE_IRQ,;這是一個(gè)數(shù)組,有兩個(gè)元素,說(shuō)明lcd占用了系統(tǒng)兩個(gè)資源,一個(gè)資源類型是IORESOURCE_MEM 代表 io 內(nèi)存,起使地址 S3C24XX_PA_LCD,這個(gè)是 LCDCON1 寄 存器的地址。另外一個(gè)資源是中斷信號(hào)線。四.platform設(shè)備驅(qū)動(dòng)如果要將
41、所寫(xiě)的驅(qū)動(dòng)程序注冊(cè)成platform驅(qū)動(dòng),那么所做的工作就是初始化一個(gè) platform_driver,然后調(diào)用 platform_driver_register 進(jìn)行注冊(cè)?;緮?shù)據(jù)機(jī)構(gòu)platform_drivercpp view plaincopystruct platform_driver int (*probe)(struct platform_device *);int ( *remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platfo
42、rm_device*, pm_message_t state);int ( *resume)(struct platform_device*);struct device_driver driver;struct platform_device_id *id_table;這是platform驅(qū)動(dòng)基本的數(shù)據(jù)結(jié)構(gòu),在驅(qū)動(dòng)程序中我們要做的就是聲明一個(gè)這樣的結(jié)構(gòu) 并初始化。下面是led驅(qū)動(dòng)程序?qū)λ某跏蓟篶pp view plaincopy1.static struct platform_driver s3c2412fb_driver = 2.probe= s3c2412fb_probe,3.rem
43、ove= s3c2410fb_remove,4.suspend = s3c2410fb_suspend,5.resume= s3c2410fb_resume,6.driver= 7.name = s3c2412-lcd,8.9.10.owner = THIS_MODULE, ,;上面幾個(gè)函數(shù)是我們要實(shí)現(xiàn)的,它將賦值給deviee_driver中的相關(guān)成員,probe函數(shù)是 用來(lái)查詢特定設(shè)備是夠真正存在的函數(shù)。當(dāng)設(shè)備從系統(tǒng)刪除的時(shí)候調(diào)用remove函數(shù)。注冊(cè)函數(shù) platform_driver_registercpp view plaincopyint platform_driver_register(struct platf
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度玻璃隔斷行業(yè)安全風(fēng)險(xiǎn)評(píng)估與控制合同3篇
- 二零二五版美容美發(fā)產(chǎn)品跨境電商銷(xiāo)售合作協(xié)議4篇
- 玻璃幕墻維修施工方案
- 二零二五版美容院供應(yīng)鏈管理及股權(quán)投資協(xié)議4篇
- 環(huán)氧砂漿施工方案
- 2025年P(guān)DA市場(chǎng)拓展專用采購(gòu)合同3篇
- 2025年度智能家居公司成立合作協(xié)議書(shū)正式版4篇
- 2025年度新型農(nóng)業(yè)貸款合同標(biāo)的特征分析3篇
- 2024版鋁單板采購(gòu)合同
- 會(huì)展搭建施工方案
- 稱量與天平培訓(xùn)試題及答案
- 超全的超濾與納濾概述、基本理論和應(yīng)用
- 2020年醫(yī)師定期考核試題與答案(公衛(wèi)專業(yè))
- 2022年中國(guó)育齡女性生殖健康研究報(bào)告
- 各種靜脈置管固定方法
- 消防報(bào)審驗(yàn)收程序及表格
- 教育金規(guī)劃ppt課件
- 呼吸機(jī)波形分析及臨床應(yīng)用
- 常用緊固件選用指南
- 私人借款協(xié)議書(shū)新編整理版示范文本
- 自薦書(shū)(彩色封面)
評(píng)論
0/150
提交評(píng)論