日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

内核驱动中常见的miscdevice、platform_device、platform_driver

發(fā)布時(shí)間:2025/4/16 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内核驱动中常见的miscdevice、platform_device、platform_driver 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
最近在看驅(qū)動(dòng)模型,是越看越糊涂,以前接觸比較多的都是一些字符驅(qū)動(dòng),對(duì)字符驅(qū)動(dòng)的框架有一定的了解。后來(lái)因?yàn)橄朐隍?qū)動(dòng)中實(shí)現(xiàn)設(shè)備文件的創(chuàng)建,又了解了一下,sysfs文件系統(tǒng)和udev設(shè)備文件系統(tǒng),必然就涉及到了驅(qū)動(dòng)模型。可是發(fā)現(xiàn)驅(qū)動(dòng)模型和以前接觸的字符驅(qū)動(dòng)沒(méi)什么聯(lián)系。
比如,以前寫(xiě)字符驅(qū)動(dòng),主要的內(nèi)容就是實(shí)現(xiàn)file_operations結(jié)構(gòu)體里的函數(shù),然后就是申請(qǐng)?jiān)O(shè)備號(hào),注冊(cè)字符設(shè)備,根本就沒(méi)有涉及到設(shè)備驅(qū)動(dòng)模型。而驅(qū)動(dòng)模型里,device_driver根本沒(méi)有涉及到設(shè)備操作的函數(shù)、file_operations等,只有一些電源管理,熱插拔相關(guān)的函數(shù)。platform_device里也主要是resource的管理,所以感覺(jué)兩者根本就沒(méi)關(guān)系,也很奇怪為什么要弄兩套東西來(lái)實(shí)現(xiàn),而且兩者也對(duì)應(yīng)不起來(lái)。
后來(lái)看了一些內(nèi)核中的驅(qū)動(dòng)源碼,發(fā)現(xiàn)很多都是用miscdevice、platform_device、platform_driver實(shí)現(xiàn)的,而且流程很相似:

1、在系統(tǒng)初始化階段注冊(cè)platform_device,主要是添加設(shè)備對(duì)應(yīng)的resource進(jìn)鏈表,以便系統(tǒng)對(duì)設(shè)備占用的資源統(tǒng)一管理;
2、實(shí)現(xiàn)platform_driver并注冊(cè),在這部分,需要實(shí)現(xiàn)的主要有platform_driver結(jié)構(gòu)體中的probe,還有remove、shutdown等一些關(guān)于熱插拔、電源管理方面的函數(shù)。
3、然后在模塊初始化函數(shù)(xx_init)里注冊(cè)platform_driver(platform_driver_register)

其中設(shè)備資源的獲取(platform_get_resource),如IO內(nèi)存、IO端口、中斷號(hào),申請(qǐng)(request),物理地址到虛擬地址的映射(ioremap),misc_device的注冊(cè)(misc_register),時(shí)鐘的獲取(clk_get)及使能(clk_enable)都是在probe函數(shù)里實(shí)現(xiàn)的,probe函數(shù)是在platform_driver注冊(cè),或者新設(shè)備添加時(shí),platform_device和platform_driver匹配(通過(guò)名字)成功后執(zhí)行的,有別于以往接觸的字符驅(qū)動(dòng)里的注冊(cè)流程。
對(duì)于misc_device對(duì)于設(shè)備操作函數(shù)的實(shí)現(xiàn)和字符設(shè)備一樣,都是填充file_operations結(jié)構(gòu)體,然后在模塊初始化函數(shù)里注冊(cè)(misc_register)。
對(duì)于platform驅(qū)動(dòng)模型,似乎就是platform_device負(fù)責(zé)設(shè)備資源,platform_driver負(fù)責(zé)電源管理以及資源的申請(qǐng),中斷的注冊(cè)等設(shè)備初始化及啟動(dòng)有關(guān)的操作,然后就是設(shè)備操作方法(file_operations)的注冊(cè)(misc_register或者cdev_add),cdev或者misc_device就負(fù)責(zé)file_operations。

但是目前還有不少疑問(wèn):
1、設(shè)備號(hào)的申請(qǐng)?jiān)谀睦?#xff0c;它是怎么放到驅(qū)動(dòng)模型里的device結(jié)構(gòu)體中的?
2、platform_driver結(jié)構(gòu)體和其中的device_driver結(jié)構(gòu)體中都有probe、remove、shutdown等,為什么要在外層放重復(fù)的東西,二者有什么關(guān)系和區(qū)別嘛?
3、misc_register實(shí)現(xiàn)里最終和platform_device_register一樣都會(huì)調(diào)用device_add,這樣在設(shè)備驅(qū)動(dòng)模型里不是有兩個(gè)device和device_driver對(duì)應(yīng),而實(shí)際的物理設(shè)備只有一個(gè)嘛?
4、看起來(lái)好像驅(qū)動(dòng)模型是對(duì)實(shí)際的設(shè)備及驅(qū)動(dòng)的抽象,提取它們的信息包裝成內(nèi)核對(duì)象kobject,然后按照它們之間的關(guān)系對(duì)其進(jìn)行分類、分層次管理(建立一棵樹(shù)),借由這些對(duì)象,由系統(tǒng)管理設(shè)備資源的注冊(cè)申請(qǐng)、釋放以及實(shí)際驅(qū)動(dòng)(file_operations)的注冊(cè)時(shí)機(jī)(由此可以實(shí)現(xiàn)熱插拔,即插即用)和電源管理(系統(tǒng)可以根據(jù)設(shè)備樹(shù)來(lái)決定設(shè)備關(guān)閉的順序,device->device_driver->shutdown)。
所以設(shè)備驅(qū)動(dòng)模型中,device只是用來(lái)建立設(shè)備樹(shù),最終會(huì)根據(jù)結(jié)構(gòu)體中的device_driver中的電源管理函數(shù)實(shí)現(xiàn)合理的電源開(kāi)關(guān)順序?
而對(duì)于熱插拔有關(guān)的功能,和device與device_driver的匹配過(guò)程有關(guān),而與設(shè)備樹(shù)層次關(guān)系無(wú)關(guān)?
以上是目前想到的不明白的地方,遺漏的地方想起會(huì)再添加。改天找老師好好問(wèn)問(wèn),太復(fù)雜了!


===============================================
最近研究Linux設(shè)備驅(qū)動(dòng)程序遇到混亂,請(qǐng)大俠過(guò)來(lái)理理頭緒。
Linux設(shè)備模型中:bus_type、device、device_driver
《Linux設(shè)備驅(qū)動(dòng)程序》的linux設(shè)備模型章中說(shuō)到設(shè)備模型中,所有設(shè)備都通過(guò)總線相連。
添加設(shè)備devA,必須指定其device結(jié)構(gòu)體的bus_type域,初始化其他域,然后調(diào)用device_register(&devA),將設(shè)備devA
注冊(cè)到指定總線。
添加該設(shè)備驅(qū)動(dòng)driverA,也必須指定其device_driver結(jié)構(gòu)體的bus_type域,初始化其他域,然后調(diào)用driver_register(&driverA),
將該驅(qū)動(dòng)注冊(cè)到總線上。
如果驅(qū)動(dòng)driverA和設(shè)備devA匹配成功,即調(diào)用probe函數(shù)成功,則建立他們之間的符號(hào)鏈接,即將設(shè)備與驅(qū)動(dòng)捆綁起來(lái)。
而實(shí)際我看Linux源代碼中卻大量使用platform_device,
struct platform_device {? ?? ??
const char? ? ? ? * name;? ?? ???
u32? ? ? ? ? ? ? ? id;? ?? ?? ?? ?? ??
struct device? ? ? ? dev;? ?? ??
u32? ? ? ? ? ? ? ? num_resources;? ???
struct resource? ? ? ? * resource;
};

struct platform_driver {? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?
int (*probe)(struct platform_device *);? ?? ?? ?? ?? ?? ?? ?? ?? ?
int (*remove)(struct 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 *);? ?? ?? ?? ?? ?? ?? ?? ???
struct device_driver driver;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???
};
從結(jié)構(gòu)體可以看出,platform_device是device派生出,platform_driver是device_driver派生出
同樣添加設(shè)備PlatformDevA,初始化platform_device結(jié)構(gòu)體的dev域時(shí),沒(méi)有初始化其bus_type域,而實(shí)際將該設(shè)備添加在sys\bus\platform\devices目錄下,
在源代碼中哪里可以看到這部分代碼。
同樣添加驅(qū)動(dòng)PlatformDrvA,初始化platform_driver結(jié)構(gòu)體的driver域時(shí),沒(méi)有初始化其bus_type域,而實(shí)際將該驅(qū)動(dòng)添加在sys\bus\platform\drivers目錄下,
在源代碼中哪里可以看到這部分代碼。

還有
struct miscdevice??{? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
int minor;? ?? ?? ?? ?? ?? ?? ?? ??
const char *name;? ?? ?? ?? ?? ?? ?
const struct file_operations *fops;
struct list_head list;? ?? ?? ?? ??
struct device *parent;? ?? ?? ?? ??
struct device *this_device;? ?? ???
};?
與字符型設(shè)備
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
從結(jié)構(gòu)體可以看出,miscdevice是device派生出,它與platform_device區(qū)別:
1、platform_device中有設(shè)備使用的資源的信息resource。
2、miscdevice中有該設(shè)備的使用方法file_operations。
從設(shè)備驅(qū)動(dòng)源代碼中:
第一步
static struct platform_device at91sam9260_adc_device = {
.name? ?? ? = "at91_adc",
.id? ???= -1,
.dev? ?? ???= {
.platform_data??= &adc_data,
},??
.resource? ?= adc_resources,
.num_resources??= ARRAY_SIZE(adc_resources),
};
static struct resource spi0_resources[] = {
[0] = {
.start??= AT91SAM9260_BASE_SPI0,
.end? ? = AT91SAM9260_BASE_SPI0 + SZ_16K - 1,
.flags??= IORESOURCE_MEM,
},
[1] = {
.start??= AT91SAM9260_ID_SPI0,
.end? ? = AT91SAM9260_ID_SPI0,
.flags??= IORESOURCE_IRQ,
},
};
//向系統(tǒng)添加此設(shè)備,注冊(cè)設(shè)備的資源
platform_device_register(&at91sam9260_adc_device);


第二步:
static struct file_operations at91_adc_fops = {
.owner =? ? ? ? THIS_MODULE,
.ioctl =? ? ? ? at91_adc_ioctl,
.read =? ? ? ? at91_adc_readdata,? ?? ??
.open =? ? ? ? ? ? ? ? at91_adc_open,? ?? ???
.release =? ? ? ? at91_adc_release,? ?? ???
};
static struct miscdevice at91_adc_dev = {? ?? ???
.minor =? ? ? ? MISC_DYNAMIC_MINOR,
.name =? ? ? ? ? ? ? ? "adc",
.fops =? ? ? ? ? ? ? ? &at91_adc_fops,
};
//向系統(tǒng)添加此設(shè)備,注冊(cè)設(shè)備的使用方法
misc_register(&at91_adc_dev);


第三步:
static struct platform_driver at91_i2c_driver = {
.probe? ? ? ? ? ? ? ? = at91_adc_probe,
.remove? ? ? ? ? ? ? ? = __devexit_p(at91_adc_remove),
.suspend? ? ? ? = at91_adc_suspend,
.resume? ? ? ? ? ? ? ? = at91_adc_resume,
.driver? ? ? ? ? ? ? ? = {
.name? ? ? ? = "at91_adc",
.owner? ? ? ? = THIS_MODULE,
},
};
//注冊(cè)此設(shè)備驅(qū)動(dòng)
platform_driver_register(&at91_i2c_driver);

這三個(gè)結(jié)構(gòu)體關(guān)系:
(基類)
kobject --------------------
/? ???\? ?? ?? ?? ?? ?? ?? ? \
/? ?? ? \? ?? ?? ?? ?? ?? ?? ? \
device? ???cdev? ?? ?? ?? ?? ?? ? driver
/? ???\ (設(shè)備驅(qū)動(dòng)操作方法)? ?? ?? ???\
/? ?? ? \? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?\
miscdevice? ?? ?? ?platform_device? ?? ?? ?? ?? ?platform_driver
(設(shè)備驅(qū)動(dòng)操作方法)? ? (設(shè)備的資源)? ?? ?? ?? ?? ?? ? (設(shè)備驅(qū)動(dòng))?
我的疑問(wèn):
1、當(dāng)寫(xiě)字符型設(shè)備驅(qū)動(dòng)時(shí),我一般只使用cdev結(jié)構(gòu)體,使用此種方式,好像無(wú)法在sysfs中顯示出該設(shè)備。
2、miscdevice是否支持字符設(shè)備和塊設(shè)備,如果使用它怎么辨別塊設(shè)備或字符設(shè)備。
3、miscdevice、platform_device、platform_driver是否可以作為通用的設(shè)備驅(qū)動(dòng)方法,由platform_device注冊(cè)設(shè)備資源
platform_driver注冊(cè)設(shè)備驅(qū)動(dòng)、miscdevice注冊(cè)設(shè)備使用方法。

===============================================
以上是網(wǎng)上搜到的一個(gè)帖子,和我的疑問(wèn)有些相似,而且有些地方我也沒(méi)搞清楚。
這個(gè)帖子轉(zhuǎn)載不少,可是少有人回復(fù),回復(fù)的也沒(méi)什么實(shí)質(zhì)性內(nèi)容。
不過(guò)這個(gè)同學(xué)整理的部分還是比較清晰的,值得看看!

總結(jié)

以上是生活随笔為你收集整理的内核驱动中常见的miscdevice、platform_device、platform_driver的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲精品一二区 | 偷自在线 | 中国少妇初尝黑人巨大 | 免费在线观看av网址 | 一区二区三区在线观看免费 | 久久久久久国产精品无码 | 亚洲天堂99 | 亚洲国产美女视频 | 精品九九久久 | 欧美性受xxxx狂喷水 | 91pron在线 | 草逼国产| 日本精品视频网站 | 亚洲av无码一区二区二三区 | 中文在线免费观看 | 啊v视频在线观看 | 欧美18免费视频 | 国产a视频免费观看 | 操女人逼逼视频 | 国产精品 欧美激情 | 欧美色老头 | 成人污视频 | 亚洲人成色777777精品音频 | 国产嫩草在线观看 | 99久久久无码国产精品性青椒 | 国产精品国产三级国产aⅴ下载 | 色xxxx | 好吊妞这里只有精品 | 亚洲综合一区二区 | 91娇羞白丝网站 | 男人的天堂影院 | 国产成人精品一区二三区四区五区 | 国产91色 | 国产欧美日韩精品在线 | 国产精品一二三区在线观看 | www夜色| 欧美大片免费高清观看 | 青青草福利视频 | 日本一级片免费看 | 日韩福利片在线观看 | 中文字幕国产一区二区 | 日本午夜网 | 91久久一区| 性做久久久 | 草久免费视频 | 激情婷婷 | 全黄一级男人和女人 | 日韩中文字幕在线一区 | 天堂在线资源8 | 致命魔术电影高清在线观看 | 欧美一级特黄aa大片 | 亚洲色图视频在线 | 在线观看福利网站 | 亚洲精品aⅴ中文字幕乱码 国产精品调教视频 | 人妻丰满熟妇av无码区免 | 亚洲日本视频在线观看 | 国产片在线 | 伊人色在线 | 日本在线色 | 台湾a级艳片潘金莲 | 宅宅少妇无码 | 销魂美女一区二区 | aaaa黄色片 | 96日本xxxxxⅹxxx17 | 国产乱人乱精一区二视频国产精品 | 亚洲视频在线一区二区 | 亚洲成人另类 | 久青草资源福利视频 | 一区二区三区在线观 | 91视频青青草 | 亚洲熟女乱综合一区二区 | 亚洲精品美女久久久 | 久久11| 亚洲一区二区视频在线观看 | 日本一区视频在线播放 | 99热在 | 亚洲成人三区 | 51啪影院| 中文字幕精品久久久久人妻红杏ⅰ | 欧洲a级片 | 欧美成人免费在线视频 | 看污网站 | 欧美国产在线一区 | 成人亚洲免费 | 亚洲欧美精品午睡沙发 | 一道本久在线中文字幕 | 欧美性俱乐部 | 8x8ⅹ国产精品一区二区二区 | av伊人久久| 97视频网址 | 亚洲一区二区偷拍 | 中文字幕3 | 久久久久亚洲av成人无码电影 | www.狠狠操.com| 国产黄色网页 | 国产午夜在线 | 国产精品传媒一区二区 | 国产免费无遮挡吸奶头视频 | 成人 黄 色 免费播放 |