某些驅(qū)動可以為指定設(shè)備的多個實例提供服務(wù)。例如,串口通信設(shè)備的單個驅(qū)動可以處理多個分割的僅參數(shù)不同的通道,比如設(shè)備地址拱撵。在VxWorks的I/O系統(tǒng)中,設(shè)備用一個稱之為設(shè)備頭(DEV_HDR)的數(shù)據(jù)結(jié)構(gòu)來定義表蝙,這個數(shù)據(jù)結(jié)構(gòu)包含設(shè)備名字符串拴测、服務(wù)這個設(shè)備的驅(qū)動設(shè)備號。在VxWorks的系統(tǒng)中勇哗,所有設(shè)備的設(shè)備頭都常駐內(nèi)存昼扛,并鏈成一個設(shè)備鏈表。設(shè)備頭是特定驅(qū)動所確定的一個大的數(shù)據(jù)結(jié)構(gòu)的起始部分欲诺,這個大的數(shù)據(jù)結(jié)構(gòu)稱之為設(shè)備描述符(device descriptor)抄谐,設(shè)備描述符除了設(shè)備頭之外,還包含諸如設(shè)備地址扰法、緩沖區(qū)蛹含、信號量等與具體設(shè)備相關(guān)的成員。
VxWorks 內(nèi)核對每個設(shè)備使用DEV_HDR 數(shù)據(jù)結(jié)構(gòu)進(jìn)行表示塞颁,該結(jié)構(gòu)定義如下:
該結(jié)構(gòu)中給出了鏈接指針(用來將該結(jié)構(gòu)串入隊列中)浦箱、驅(qū)動索引號、設(shè)備節(jié)點名等祠锣。這個結(jié)構(gòu)較為簡單酷窥,只存儲了一些設(shè)備關(guān)鍵系統(tǒng)。底層驅(qū)動對其驅(qū)動的設(shè)備都有一個自定義的數(shù)據(jù)結(jié)構(gòu)表示伴网,最關(guān)鍵的一點是DEV_HDR內(nèi)核結(jié)構(gòu)必須是這個自定義的數(shù)據(jù)結(jié)構(gòu)的第一個成員變量蓬推。我們的自定義數(shù)據(jù)結(jié)構(gòu)如下:
之后為了能夠讓用戶對設(shè)備進(jìn)行操作,驅(qū)動必須要將設(shè)備注冊到I/O子系統(tǒng)澡腾,這個過程也被稱為是創(chuàng)建設(shè)備節(jié)點沸伏。I/O子系統(tǒng)提供iosDevAdd()函數(shù)用于被驅(qū)動調(diào)用來注冊一個設(shè)備:
iosDevAdd()函數(shù)將一個設(shè)備添加到I/O子系統(tǒng)維護(hù)的系統(tǒng)的設(shè)備列表當(dāng)中。該列表是一個隊列动分,隊列中的成員通過指針鏈接在一起毅糟,這是由DEV_HDR 結(jié)構(gòu)中的node 成員變量完成的。系統(tǒng)設(shè)備列表由iosDvList內(nèi)核變量指向澜公,如圖所示為系統(tǒng)設(shè)備列表示意圖姆另。
非塊設(shè)備通過調(diào)用內(nèi)部例程iosDevAdd()被動態(tài)添加到I/O系統(tǒng)中,iosDevAdd()的參數(shù)包含這個新設(shè)備的設(shè)備描述符地址、設(shè)備名字蜕青、以及服務(wù)該設(shè)備的驅(qū)動的驅(qū)動號苟蹈。設(shè)備描述符是由驅(qū)動所指定的糊渊,其中包含必須的與設(shè)備相關(guān)的信息右核,但是必須以設(shè)備頭作為該設(shè)備描述符的第一個成員。驅(qū)動不需要添加設(shè)備描述符的設(shè)備頭部分渺绒,只需要填寫設(shè)備描述符中與具體設(shè)備相關(guān)的信息贺喝。iosDevAdd()例程負(fù)責(zé)填寫設(shè)備頭中的設(shè)備名、設(shè)備號宗兼,并把該設(shè)備添加到系統(tǒng)設(shè)備鏈表中躏鱼。下圖展示一個驅(qū)動的設(shè)備創(chuàng)建例程xxxxDevCreate()通過調(diào)用iosDevAdd()添加一個設(shè)備到I/O系統(tǒng)當(dāng)中: