Vxworks內核驅動基本結構:
三張表:1. 系統設備表 2. 系統驅動表 3. 文件描述符表
Vxworks 內部對每個設備使用DEV_HDR 數據結構進行表示:
Typedef struct
{
DL_NODE node;
Short drvnum;
Char *name;
}
該結構中給出了鏈接指針(用以將該結構串入隊列中)、驅動索引號、設備節點名稱。內核提供這個結構較為簡單,只存儲了一些設備的關鍵信息。底層驅動對其驅動的設備都有一個自定義數據結構表示,其中包含了驅動設備寄存器基地址,中斷號,可能的數據緩沖區,保存內核回調函數的指針,以及一些標志位。最關鍵的一點是DEV_HDR必須是自定義數據結構的第一個成員變量,因為這個用戶自定義結構最后需要添加到系統設備隊列中,必須能夠在用戶定義結構與DEV_HDR結構之間進行轉換,而將DEV_HDR結構設置為用戶自定義結構的第一個成員變量就可以達到目的。
typedef struct
{
DEV_HDR pFCcardHdr;
BOOL created;
char * buf_virts;
UINT32 iobase;
UINT32 membase;
char irq;
UINT32 irqvec;
UINT32 pciBus;
UINT32 pciDevice;
UINT32 pciFunc;
}DRV_CTRL;
注:該結構是結合本人開發定義的Pci設備結構,后面的文章將會涉及到具體的開發。
系統提供了iosDevAdd(DEV_HDR *pDevHdr, char *name, int drvnum)用於驅動程序調用注冊一個設備。
第三個參數是設備對應的驅動程序索引號。這個驅動號是iosDrvInstall函數的返回值,在設備初始化函數中,我們首先調用iosDrvInstall注冊驅動,然后使用iosDrvInstall 函數返回的驅動號調用 iosDevAdd添加設備到系統中
通過這兩步設備就可以被用戶程序使用了。
用戶調用open函數打開一個設備文件時,系統將以傳入的文件路徑名匹配系統設備的設備節點名,匹配方式是最佳匹配。
系統驅動表:
系統驅動表包含了當前注冊到I/O子系統下的所有驅動。這些驅動可以直接驅動硬件工作的驅動層。系統驅動表底層實現是一個數組,數組元素數目在內核初始化過程中指定。I/O子系統提供iosDrvInstall供驅動程序注冊,iosDrvInstall原型如下:
Int iosDrvInstall
(
FUNCPTR pCreate, FUNCPTR pDelete,
FUNCPTR pOpen, FUNCPTR pClose,
FUNCPTR pRead, FUNCPTR pWrite,
FUNCPTR pIoctl /*pointer to driver ioctl function*/
)
一個設備驅動在初始化過程中一方面完成硬件設備寄存器配置,另一方面就是向I/O子系統注冊驅動和設備。
一個驅動並不需要實現上述所有函數,無須實現的函數直接傳遞NULL指針就可以了。
iosDrvInstall 函數的基本實現即遍歷drvTable數組,查詢一個空閑表項,用傳入的函數地址對各成員變量進行初始化。
系統文件描述符表
文件描述符表表項索引被用做文件描述符ID,即open函數返回值。對於文件描述符,需要注意:標准輸入、標准輸出、標准錯誤輸出雖然使用0,1,2三個文件描述符,但是可能在系統文件描述符表中只占用一個表項,即都使用同一個表項。Vxworks內核將0,1,2三個標准文件描述符與系統文件描述符表中的內容分開進行管理。
系統文件描述符中的內容主要是針對硬件設備,使用一次open函數調用就占用一個表項:
int fd = open(DevName, 2,0);
應用程序每調用一次open函數,系統文件描述符表中就增加一個有效表項,直到數組滿為止。此時open函數調用將以失敗返回,因此注意如果需要反復打開設備的話,一定要在設備不用的時候調用close函數關閉該描述符指向的設備,並在每次調用open函數之后檢查返回的文件描述符是否合法。
用戶請求服務過程