0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

設(shè)備驅(qū)動(dòng)模型直觀的認(rèn)識

Q4MP_gh_c472c21 ? 來源:未知 ? 作者:李倩 ? 2018-05-18 14:58 ? 次閱讀

Linux早期時(shí)候,一個(gè)驅(qū)動(dòng)對應(yīng)一個(gè)設(shè)備,也就對應(yīng)一個(gè)硬件地址,那當(dāng)有兩個(gè)一樣的設(shè)備的時(shí)候,就要寫兩個(gè)驅(qū)動(dòng),顯然是不合理的。應(yīng)該是從Linux2.5開始,就引入了device-bus-driver模型。 其中設(shè)備驅(qū)動(dòng)模型主要結(jié)構(gòu)分為kset、kobject、ktype。

kset是同類型kobject對象的集合,可以說是一個(gè)容器。

kobject是總線、驅(qū)動(dòng)、設(shè)備的三種對象的一個(gè)基類,實(shí)現(xiàn)公共接口。

ktype,記錄了kobject對象的一些屬性。

設(shè)備驅(qū)動(dòng)模型的核心即是kobject,是為了管理日益增多的設(shè)備,使得設(shè)備在底層都具體統(tǒng)一的接口。他與sysfs文件系統(tǒng)緊密相連,每個(gè)注冊的kobject都對應(yīng)sysfs文件系統(tǒng)中的一個(gè)目錄。為了直觀管理,統(tǒng)一存放的路徑,使用了kset。但是僅僅有這些目錄沒有意義,這兩個(gè)結(jié)構(gòu)體只能表示出設(shè)備的層次關(guān)系,所以基本不單獨(dú)使用,會嵌入到更大的結(jié)構(gòu)體中,(如希望在驅(qū)動(dòng)目錄下能看到掛在該總線上的各種驅(qū)動(dòng),而在設(shè)備目錄下能看到掛在該總線的各種設(shè)備,就將kobject嵌入到描述設(shè)備以及驅(qū)動(dòng)的結(jié)構(gòu)體中,這樣每次注冊設(shè)備或驅(qū)動(dòng),都會在sys目錄下有描述)

放上一個(gè)經(jīng)典的圖:

這個(gè)圖其實(shí)還漏了一個(gè)ktype,kobject都應(yīng)該包含一個(gè)ktype。

Linux設(shè)備模型的目的是:為內(nèi)核建立起一個(gè)統(tǒng)一的設(shè)備模型,從而有一個(gè)對系統(tǒng)結(jié)構(gòu)的一般性抽象描述。

我們可以先看下一個(gè)小的測試程序:

可以看到,我們在使用kobject、kset、ktype結(jié)構(gòu),就在sysfs虛擬文件系統(tǒng)下創(chuàng)建(通過kset_create_and_add和kobject_init_and_add函數(shù))了一些子目錄(kobject_test)和屬性文件。kset和kobject都可以創(chuàng)建出目錄,但是kset的目錄下存放kobject目錄,kobject下存放屬性文件(可以對屬性文件進(jìn)行讀寫操作,如上圖name屬性文件,而且kobject目錄下也可以存放kobject目錄,只需parent指向它即可)。

這個(gè)小程序沒看懂?沒關(guān)系,先看下面的分析:(看到文章末尾再回頭看這個(gè)程序,你會有更直觀的理解)

我們對著Linux kernel源碼分析下,可以下看看三個(gè)結(jié)構(gòu)體的成員:

其實(shí)說到設(shè)備驅(qū)動(dòng)模型,很容易想到platform,下面我們就來具體分析這個(gè)吧:

init/main.c里:

這是driver_init函數(shù):

我們看下devices_init函數(shù):

這里面調(diào)用kset_create_and_add創(chuàng)建kset并返回給devices_kset,注意這里的devices_kset,可以說是/sys下最大的boss之一了,所有的物理設(shè)備都會在device目錄下管理,/sys/device/目錄是內(nèi)核對系統(tǒng)中所有設(shè)備的分層次表達(dá)模型,保存了系統(tǒng)所有的設(shè)備。

然后調(diào)用kobject_create_and_add函數(shù)在/sys/目錄下創(chuàng)建dev目錄,/sys/dev目錄下維護(hù)一個(gè)按照字符設(shè)備和塊設(shè)備的主次號碼(major:minor)鏈接到真是設(shè)備(/sys/devices)的符號鏈接文件,應(yīng)用程序通過對這些文件的讀寫和控制,可以訪問實(shí)際的設(shè)備。

最后再以dev_kobj為父節(jié)點(diǎn),在/sys/dev/目錄下創(chuàng)建block和char目錄。

這里我們先看kobject_create_and_add函數(shù),再分析kset_create_and_add函數(shù):

其實(shí)里面函數(shù)也沒啥,先創(chuàng)建kobject,初始化它,再添加,沒啥好說的。

倒是除了kobject_create_and_add函數(shù),還有一個(gè)類似的函數(shù):kobject_init_and_add。

kobject_init_and_add傳入一個(gè)kobject指針和kobj_type指針,然后進(jìn)行初始化

kobject_create_and_add創(chuàng)建一個(gè)kobject變量,并返回其指針,它不用傳入kobj_type指針

在kset_create_and_add函數(shù)里也會用到kobject,所以我們現(xiàn)在來分析下kset_create_and_add函數(shù):

里面就是具體的創(chuàng)建和注冊kset了。

先說創(chuàng)建函數(shù):

staticstructkset *kset_create(constchar*name,

conststructkset_uevent_ops *uevent_ops,

structkobject *parent_kobj)

{

structkset *kset;

intretval;

kset = kzalloc(sizeof(*kset), GFP_KERNEL);//分配kset空間

if(!kset)

returnNULL;//失敗就返回

retval = kobject_set_name(&kset->kobj, "%s", name);//設(shè)置kset的名字,也即內(nèi)嵌kobject的名字

if(retval) {

kfree(kset);

returnNULL;

}

kset->uevent_ops = uevent_ops;//kset屬性操作

kset->kobj.parent= parent_kobj;//設(shè)置其parent

kset->kobj.ktype= &kset_ktype;//ktype指定為kset_ktype

kset->kobj.kset= NULL;

returnkset;

}

可以看出kset_create函數(shù)內(nèi)容為:

1)調(diào)用kobject_set_name函數(shù)設(shè)置kobject的名稱2)設(shè)置kobject的uevent_ops、parent為傳入的形參uevent_ops、parent_kobj3)設(shè)置kobject的ktype為系統(tǒng)定義好的ktype變量4)設(shè)置kobject的所屬kset為NULL,意思是kobject所屬的kset就是kset本身,因?yàn)閗set結(jié)構(gòu)體包含了一個(gè)kobject成員。

這里需要一個(gè)注意的,就是ktype 這個(gè)結(jié)構(gòu),即kset_ktype:

這里填充了一個(gè)釋放函數(shù),每個(gè)kobject必須有一個(gè)釋放函數(shù),并且這個(gè)kobject必須保持直到這個(gè)釋放函數(shù)被調(diào)用到。如果這個(gè)條件不能被滿足,則這個(gè)代碼是有缺陷的。注意,假如你忘了提供釋放函數(shù),內(nèi)核會提出警告的;不要嘗試提供一個(gè)空的釋放函數(shù)來消除這個(gè)警告,你會收到kobject維護(hù)者的無情嘲笑。

至于kobj_sysfs_ops,則是關(guān)于讀寫操作相關(guān)的操作集:

讀文件時(shí),會調(diào)用到.show的回調(diào)函數(shù)。寫文件時(shí),會調(diào)用到.store的回調(diào)函數(shù)。

看完了創(chuàng)建函數(shù),接下來是注冊函數(shù):

kset_init函數(shù)主要是對kset初始化,會將初始化引用計(jì)數(shù)器(即kobj->kref)為1(當(dāng)計(jì)數(shù)器引用計(jì)數(shù)沒到0之前不可以被釋放)。接著初始化entry鏈表結(jié)點(diǎn),用于與所屬的kset的list成員組成鏈表(INIT_LIST_HEAD(&kobj->entry)),以及一些參數(shù)的賦值。最后,還初始化以list成員為頭結(jié)點(diǎn)的鏈表,它和子kobject的entry成員組成鏈表(INIT_LIST_HEAD(&k->list))。

kobject_add_internal函數(shù)就是關(guān)鍵的kobject函數(shù)了:

static intkobject_add_internal(struct kobject *kobj)

{

interror= 0;

struct kobject *parent;

if(!kobj)

return-ENOENT;

if(!kobj->name || !kobj->name[0]) {//如果kobject的名字為空.退出

WARN(1, "kobject: (%p): attempted to be registered with empty "

"name!\n", kobj);

return-EINVAL;

}

parent= kobject_get(kobj->parent);//如果kobj-parent為真,則增加kobj->kref計(jì)數(shù),即父節(jié)點(diǎn)的引用計(jì)數(shù)

/* join kset if set, use it as parent if we do not already have one */

if(kobj->kset) {

if(!parent)

parent= kobject_get(&kobj->kset->kobj);//如果parent父節(jié)點(diǎn)為NULL那么就用kobj->kset->kobj作其父節(jié)點(diǎn),并增加其引用計(jì)數(shù)

kobj_kset_join(kobj);//把kobj的entry成員添加到kobj->kset>list的尾部,現(xiàn)在的層次就是kobj->kset->list指向kobj->entry

kobj->parent= parent;

}

/*刪除了部分調(diào)試內(nèi)容*/

error= create_dir(kobj);//利用kobj創(chuàng)建目錄和屬性文件,其中會判斷,如果parent為NULL那么就在sysfs_root_kn下創(chuàng)建

if(error) {

/*刪除了部分內(nèi)容*/

} else

kobj->state_in_sysfs = 1;//如果創(chuàng)建成功。將state_in_sysfs建為1。表示該object已經(jīng)在sysfs中了

returnerror;

}

kobject_add_internal函數(shù)內(nèi)容在注釋里都寫好了,可以概括為:

1)如果kobject的parent成員為NULL,則把它指向kset的kobject成員。2)如果kobject的kset成員不為NULL,它會調(diào)用kobj_kset_join函數(shù)把kobject的entry成員添加到kset的list鏈表中3)最后調(diào)用create_dir函數(shù)創(chuàng)建sys目錄

注冊函數(shù)里最后一個(gè)調(diào)用就是kobject_uevent函數(shù)了,應(yīng)該是關(guān)于熱拔插機(jī)制的,這不是我們現(xiàn)在關(guān)心的內(nèi)容。

好了,經(jīng)過上面的折騰,就會在/sys/目錄下建立一個(gè)devices目錄。

接下來繼續(xù)回到文章開頭進(jìn)入到的devices_init函數(shù):

我們之前分析的是devices_init函數(shù),其實(shí)接下來幾個(gè)函數(shù)都是一樣的,在/sys/目錄下創(chuàng)建各個(gè)目錄。

只需要記住devices_kset對應(yīng)/sys/devices目錄bus_kset對應(yīng)/sys/bus目錄devices_kset對應(yīng)/sys/devices目錄system_kset對應(yīng)/sys/devices/system目錄class_kset對應(yīng)/sys/class目錄firmware_kobj對應(yīng)/sys/firmware目錄hypervisor_kobj對應(yīng)/sys/hypervisor目錄

接下來看下platform_bus_init函數(shù)

也就是我們之前用的platform總線了??!

在driver/base/platform.c文件:

這里,device_register就是在/sys/device/目錄下創(chuàng)建platform

其實(shí)也就包含兩個(gè)函數(shù),一個(gè)初始化,一個(gè)添加:

voiddevice_initialize(struct device *dev)

{

dev->kobj.kset =devices_kset;//設(shè)置設(shè)備的kobject所屬集合,devices_kset即對應(yīng)/sys/devices/

kobject_init(&dev->kobj, &device_ktype);//初始化設(shè)備的kobject

INIT_LIST_HEAD(&dev->dma_pools);//初始化設(shè)備的DMA池,用于傳遞大數(shù)據(jù)

mutex_init(&dev->mutex);

lockdep_set_novalidate_class(&dev->mutex);

spin_lock_init(&dev->devres_lock);//初始化自旋鎖,用于同步子設(shè)備鏈表

INIT_LIST_HEAD(&dev->devres_head);//初始化子設(shè)備鏈表頭

device_pm_init(dev);

set_dev_node(dev, -1);#ifdefCONFIG_GENERIC_MSI_IRQ

INIT_LIST_HEAD(&dev->msi_list);#endif

}

注釋都寫好了,看下device_add函數(shù):

int device_add(struct device *dev)

{

struct device *parent=NULL;

struct kobject *kobj;

struct class_interface *class_intf;

int error =-EINVAL;

struct kobject *glue_dir =NULL;

dev =get_device(dev);//增加設(shè)備的kobject的引用計(jì)數(shù)

if(!dev)

goto done;

if(!dev->p) {

error =device_private_init(dev);//初始化dev的私有成員,及其鏈表操作函數(shù)

if(error)

goto done;

}

if(dev->init_name) {//保存設(shè)備名,以后需要獲取時(shí)使用dev_name函數(shù)獲取

dev_set_name(dev, "%s", dev->init_name);

dev->init_name =NULL;

}

/* subsystems can specify simple device enumeration */

if(!dev_name(dev) &&dev->bus &&dev->bus->dev_name)

dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);

if(!dev_name(dev)) {

error =-EINVAL;

goto name_error;

}

pr_debug("device: '%s': %s\n", dev_name(dev), __func__);

parent=get_device(dev->parent);//返回父節(jié)點(diǎn),增加父節(jié)點(diǎn)引用計(jì)數(shù),如果沒有返回NULL

kobj =get_device_parent(dev, parent);//以上層devices為準(zhǔn)重設(shè)dev->kobj.parent

if(kobj)

dev->kobj.parent=kobj;

/* use parent numa_node */

if(parent&&(dev_to_node(dev) ==NUMA_NO_NODE))

set_dev_node(dev, dev_to_node(parent));

/* first, register with generic layer. */

/* we require the name to be set before, and pass NULL */

error =kobject_add(&dev->kobj, dev->kobj.parent, NULL);//設(shè)置dev->kobj的名字和父對象,并建立相應(yīng)目錄

if(error) {

glue_dir =get_glue_dir(dev);

goto Error;

}

/* notify platform of device entry */

if(platform_notify)

platform_notify(dev);

error =device_create_file(dev, &dev_attr_uevent);//建立uevent屬性文件

if(error)

goto attrError;

error =device_add_class_symlinks(dev);

if(error)

goto SymlinkError;

error =device_add_attrs(dev);

if(error)

goto AttrsError;

error =bus_add_device(dev);

if(error)

goto BusError;

error =dpm_sysfs_add(dev);

if(error)

goto DPMError;

device_pm_add(dev);

if(MAJOR(dev->devt)) {

error =device_create_file(dev, &dev_attr_dev);//在sys下產(chǎn)生dev屬性文件

if(error)

goto DevAttrError;

error =device_create_sys_dev_entry(dev);//在/sys/dev目錄建立對設(shè)備的軟鏈接

if(error)

goto SysEntryError;

devtmpfs_create_node(dev);

}

/* Notify clients of device addition. This call must come

* after dpm_sysfs_add() and before kobject_uevent().

*/

if(dev->bus)

blocking_notifier_call_chain(&dev->bus->p->bus_notifier,

BUS_NOTIFY_ADD_DEVICE, dev);

kobject_uevent(&dev->kobj, KOBJ_ADD);//向用戶空間發(fā)出KOBJ_ADD 事件

bus_probe_device(dev);//檢測驅(qū)動(dòng)中有無適合的設(shè)備進(jìn)行匹配,現(xiàn)在只添加了設(shè)備,還沒有加載驅(qū)動(dòng),所以不會進(jìn)行匹配

if(parent)

klist_add_tail(&dev->p->knode_parent,

&parent->p->klist_children);//把該設(shè)備的節(jié)點(diǎn)掛到其父節(jié)點(diǎn)的鏈表

if(dev->class) {

mutex_lock(&dev->class->p->mutex);

/* tie the class to the device */

klist_add_tail(&dev->knode_class,

&dev->class->p->klist_devices);

/* notify any interfaces that the device is here */

list_for_each_entry(class_intf,

&dev->class->p->interfaces, node)

if(class_intf->add_dev)

class_intf->add_dev(dev, class_intf);

mutex_unlock(&dev->class->p->mutex);

}

/*省略部分error內(nèi)容*/

}

device_add函數(shù)是比較重要的,注釋基本都寫好了,可以概括為:

1)增加kobj->kref計(jì)數(shù)2)初始化dev的私有成員3)設(shè)置設(shè)備名稱4)增加父節(jié)點(diǎn)引用計(jì)數(shù)5)將dev->kobj添加到dev->kobj.parent對應(yīng)目錄下6)dev->kobj下創(chuàng)建屬性文件7)在/sys/dev目錄建立對設(shè)備的軟鏈接8)驅(qū)動(dòng)檢測

其中,驅(qū)動(dòng)檢測函數(shù):bus_probe_device可以自行百度一下。

最后,我們接著看 bus_register(&platform_bus_type);

今天篇幅有點(diǎn)長了,函數(shù)就寫點(diǎn)重要的即可:

再次強(qiáng)調(diào):

priv->subsys.kobj.kset = bus_kset;priv->subsys.kobj.ktype = &bus_ktype;

這里設(shè)置了所屬的kset和ktype。ktype結(jié)構(gòu)體里包含了sysfs_ops結(jié)構(gòu)體,里面就是對文件的讀寫操作:

最后,bus_register函數(shù)里還調(diào)用了kset_create_and_add函數(shù)在/sys/platform/目錄下創(chuàng)建devices和drivers目錄,里面存放我們platform平臺下注冊的設(shè)備和驅(qū)動(dòng)。

好了,到此,我們就來再次小小歸納下 :

在kset下還可能會有更深的kset

kset包含一個(gè)或多個(gè)kobject,方便管理

kobject并不一定需要kset

kobject下有屬性文件,·向用戶層提供了表示和操作這個(gè) kobject 的屬性特征的接口

kobject 下還有一些符號鏈接文件,指向其它的 kobject

現(xiàn)在,是不是對設(shè)備驅(qū)動(dòng)模型有了更為直觀的認(rèn)識?現(xiàn)在回頭看看文章開頭的小程序,是不是輕而易舉的理解了呢?

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11332

    瀏覽量

    210023
  • 設(shè)備驅(qū)動(dòng)

    關(guān)注

    0

    文章

    68

    瀏覽量

    10909

原文標(biāo)題:面試如果被問到Linux設(shè)備驅(qū)動(dòng)模型怎么答?看完這篇就能給出滿意答案了

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    總線設(shè)備驅(qū)動(dòng)模型淺析

    本帖最后由 weidongshan 于 2017-9-27 15:40 編輯 復(fù)習(xí)總線設(shè)備驅(qū)動(dòng)模型,做了一點(diǎn)小筆記,大牛略過。一、Linux系統(tǒng)的驅(qū)動(dòng)框架的基礎(chǔ)很大一部分是圍繞著
    發(fā)表于 08-22 16:19

    字符設(shè)備驅(qū)動(dòng),平臺設(shè)備驅(qū)動(dòng),設(shè)備驅(qū)動(dòng)模型,sysfs的比較

    字符設(shè)備驅(qū)動(dòng),平臺設(shè)備驅(qū)動(dòng),設(shè)備驅(qū)動(dòng)模型,sysfs
    發(fā)表于 09-03 12:04

    字符設(shè)備驅(qū)動(dòng)、設(shè)備驅(qū)動(dòng)模型、sysfs、平臺設(shè)備驅(qū)動(dòng)的關(guān)系 -----從需求的角度去理解Linux之三

    學(xué)習(xí)Linux設(shè)備驅(qū)動(dòng)開發(fā)的過程中自然會遇到字符設(shè)備驅(qū)動(dòng)、平臺設(shè)備驅(qū)動(dòng)、
    發(fā)表于 12-17 16:16

    詳解linux設(shè)備驅(qū)動(dòng)模型架構(gòu)

    LDD3中說:“Linux內(nèi)核需要一個(gè)對系統(tǒng)結(jié)構(gòu)的一般性描述?!边@個(gè)描述就是linux設(shè)備驅(qū)動(dòng)模型(下面簡稱為LDDM)。LDDM不是獨(dú)立存在,其體系如下圖所示:
    發(fā)表于 07-25 07:25

    基于總線設(shè)備驅(qū)動(dòng)模型的LED驅(qū)動(dòng)的相關(guān)資料分享

    繼續(xù)來點(diǎn)燈~學(xué)了一段時(shí)間的嵌入式Linux發(fā)現(xiàn)LED程序挺香的。。我們可以從LED程序中榨取很多知識:基本的驅(qū)動(dòng)框架、驅(qū)動(dòng)的簡單分層、驅(qū)動(dòng)的分層+分離思想、總線設(shè)備
    發(fā)表于 12-24 07:25

    機(jī)械展示、認(rèn)識與分析直觀現(xiàn)場教學(xué)

    實(shí)驗(yàn)五 機(jī)械展示、認(rèn)識與分析直觀現(xiàn)場教學(xué) 一、實(shí)驗(yàn)?zāi)康牧私飧髁悴考慕Y(jié)構(gòu)和工作原理,增加感性認(rèn)識,鞏固課堂教學(xué)。
    發(fā)表于 03-13 19:00 ?2034次閱讀

    Linux設(shè)備驅(qū)動(dòng)模型摘抄

    Linux2.6 內(nèi)核提供了新的設(shè)備模型,目的是為了對計(jì)算機(jī)上的所有設(shè)備進(jìn)行統(tǒng)一地表示和操作,包括設(shè)備本身和設(shè)備之間的連接關(guān)系。這個(gè)
    發(fā)表于 03-19 15:15 ?39次下載

    深度解析字符設(shè)備驅(qū)動(dòng)模型

    ,read,write和ioctl等例程。所以根據(jù)應(yīng)用不同,字符驅(qū)動(dòng)能會調(diào)用其他驅(qū)動(dòng)模塊,如i2c、spi和v4l2等,于是字符驅(qū)動(dòng)還可分WDT驅(qū)動(dòng)、RTC
    發(fā)表于 10-17 10:09 ?0次下載

    Linux設(shè)備驅(qū)動(dòng)模型摘抄

    Linux設(shè)備驅(qū)動(dòng)模型摘抄
    發(fā)表于 10-31 09:00 ?8次下載
    Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>的<b class='flag-5'>模型</b>摘抄

    你知道Linux設(shè)備驅(qū)動(dòng)模型是怎么樣構(gòu)成的?

    Linux設(shè)備模型的目的:為內(nèi)核建立一個(gè)統(tǒng)一的設(shè)備模型,從而又一個(gè)對系統(tǒng)結(jié)構(gòu)的一般性抽象描述。換句話說,Linux設(shè)備
    發(fā)表于 04-28 17:26 ?863次閱讀
    你知道Linux<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>模型</b>是怎么樣構(gòu)成的?

    驅(qū)動(dòng)之路-設(shè)備模型之上層模型

    底層模型決定上層模型,在總線,設(shè)備驅(qū)動(dòng)的結(jié)構(gòu)體中你總是可以看到它們間接或者直接的包含了kobject結(jié)構(gòu)或kset結(jié)構(gòu)。
    發(fā)表于 05-15 17:04 ?649次閱讀
    <b class='flag-5'>驅(qū)動(dòng)</b>之路-<b class='flag-5'>設(shè)備</b><b class='flag-5'>模型</b>之上層<b class='flag-5'>模型</b>

    如何正確認(rèn)識Linux設(shè)驅(qū)動(dòng)模型

    Linux設(shè)備林林總總,嵌入式開發(fā)一個(gè)繞不開的話題就是設(shè)備驅(qū)動(dòng)開發(fā),在做具體設(shè)備驅(qū)動(dòng)開發(fā)之前,有必要對Linux設(shè)
    的頭像 發(fā)表于 09-13 09:30 ?2181次閱讀
    如何正確<b class='flag-5'>認(rèn)識</b>Linux設(shè)<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>模型</b>

    Linux總線、設(shè)備驅(qū)動(dòng)模型的探究

    Linux總線、設(shè)備驅(qū)動(dòng)模型的探究
    發(fā)表于 02-14 12:01 ?7次下載

    一文帶你直觀認(rèn)識片上儀器

    一個(gè)芯片搭載十?dāng)?shù)種儀器功能,測量儀器正不斷突破與創(chuàng)新,它能做些什么?6分鐘視頻帶你直觀認(rèn)識片上儀器。
    的頭像 發(fā)表于 05-05 10:49 ?2085次閱讀

    Linux USB設(shè)備驅(qū)動(dòng)模型查看

    1. BUS/DEV/DRV 模型 "USB 接口"是邏輯上的 USB 設(shè)備 ,編寫的 usb_driver 驅(qū)動(dòng)程序,支持的是"USB 接口": USB 控制器或 Hub 識別出 USB 設(shè)
    的頭像 發(fā)表于 07-17 17:38 ?1005次閱讀
    Linux USB<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>模型</b>查看