1、VxWorks設備驅動結構
首先在終端輸入iosFdShow,此命令用來顯示已經打開的設備信息。
- fd 是設備描述符,open函數返回以後供read, write等函數使用。
- name 設備的名字。
- drv 對應的驅動程序索引。
在終端輸入 devs:
- drv 對應上一幅圖中的drv。
- name 設備名稱。
在終端輸入iosDrvShow
可以看到,該表通過drv索引到7個函數。
以上就是vxworks設備驅動程序的三張表。這三張表是怎麼生成的呢?首先我們來看一下驅動創建的過程:
這裏要用到兩個函數iosDrvInstall和iosDevAdd。在vxworks的bsp文件中執行iosDrvInstall,會返回一個drv,這個drv就是上面三張表中的drv。也就是說,每次向內核添加一個驅動時,內核就會返回一個設備驅動的索引。
在來看一下 iosDevAdd (DEV_HDR * pDevHdr, const char * name, int drvnum)函數。調用該函數需要傳入三個參數,drvnum是iosDrvInstall返回的,name就是設備的名字。重點來分析下DEV_HDR * pDevHdr,該結構用來創建設備列表。該結構在系統中做如下定義
typedef struct
{
DL_NODE node; //設備節點
short drvNum; //驅動號
char * name; //設備名稱
}DEV_HDR;
在使用該函數時候,需要創建一個關於DEV_HDR的實例。如下:
typedef struct
{
DEV_HDR devHdr;
int ix;
BOOL Opened;
BOOL RdReady;
BOOL WrReady;
}gh_DEV;
int bsp_hello(char *devName)
{
printf("hello world\n");
LOCAL int ghDrvNum=0; //driver index num
ghDrvNum = iosDrvInstall(testOpen, NULL, testOpen, testclose, testread, testwrite, NULL);
gh_DEV *pghDev = (gh_DEV *)malloc(sizeof(gh_DEV));
bzero(pghDev,sizeof(gh_DEV));
pghDev->WrReady= 1; /*Initial gh_Dev*/
iosDevAdd(&pghDev->devHdr,devName,ghDrvNum);
return 0;
}
通過以上的步驟,把三張表聯繫到了一起。
在iosDrvInstall(testOpen, NULL, testOpen, testclose, testread, testwrite, NULL);函數中註冊了設備驅動的接口函數。
以下是所有代碼:
#include <stdio.h>
#include "vxworks.h"
#include "tasklib.h"
#include "syslib.h"
#include "config.h"
#include "vmlib.h"
typedef struct
{
DEV_HDR devHdr;
int ix; //
BOOL Opened;
BOOL RdReady;
BOOL WrReady;
}gh_DEV;
int testOpen(DEV_HDR *path ,int opt , int flags)
{
gh_DEV* rel = (gh_DEV *)path;
printf("enter %s \n",__FUNCTION__);
return (int)rel;
}
int testclose(int devid)
{
printf("enter %s \n",__FUNCTION__);
}
int testread(int fd ,char *buf ,size_t nbyte)
{
printf("enter %s \n",__FUNCTION__);
return 0;
}
int testwrite(int fd ,char *buf ,size_t nbyte)
{
printf("enter %s \n",__FUNCTION__);
return 0;
}
int bsp_hello(char *devName)
{
printf("hello world\n");
LOCAL int ghDrvNum=0; //driver index num
ghDrvNum = iosDrvInstall(testOpen, NULL, testOpen, testclose, testread, testwrite, NULL);
gh_DEV *pghDev = (gh_DEV *)malloc(sizeof(gh_DEV));
bzero(pghDev,sizeof(gh_DEV));
pghDev->WrReady= 1; /*Initial gh_Dev*/
iosDevAdd(&pghDev->devHdr,devName,ghDrvNum);
return 0;
}
這部分代碼只是簡單的實現了應用層通過調用統一的系統調用接口,open,read等函數,來實現對驅動驅動程序的抽象。並沒有涉及到實際硬件的操作。(其實有了接口以後,硬件的操作和單片機一樣了),之後會介紹驅動和中斷的鏈接。
以上代碼需要注意的是,在open函數中通過獲取設備的描述結構,返回給應用層一個設備描述。供其他系統調用使用。