發現pci設備


pci設備驅動開發,首先是要發現pci設備,從中獲得pci設備的配置空間,並從中得到基本基本的資源信息。

首先進行pci設備查找的函數為:

STATUS pciFindDevice



int vendorId,

int deviceId,

int index,

int *pBusNo,

int *pDeviceNo,

int *pFuncNo


函數中的參數從命名來看都很好理解,注意第三個參數 ‘index’,這是在系統中有多個pci設備時我們需要從0開始查找,知道查找到我們想要驅動設備(第一個參數vendorId和第二個參數deviceId相同的設備)。

從參數列表中我們可以看到,后面三個參數都是指針類型,這三個參數就是唯一標識該pci設備的資源參數,也是我們在查找pci設備的時候需要獲得該設備空間中的pci設備資源。

根據上面的說明我們可以寫出這樣的代碼來查找pci設備:

int pciBus, pciDevice, pciFunc;

int found = 0;

int i;

for (i=0; i<DEV_MAX_NUM; i++) {

if (pciFindDevice(VENDOR_ID,DEVICE_ID,i,&pciBus,&pciDevice,&pciFunc)

== OK) {

found = TRUE;

printf("pci device found!\n");

break;

}

}


注:一定要保證VENDOR_ID,DEVICE_ID的正確性。可以將設備上電之后通過pciDeviceShow命令來查看系統中pci設備的詳細信息。為了安全起見最好,打印設備已經找到的信息。如上例,如果找不到函數應該立刻返回。代碼中的found就是用來預防找不到設備的情況。

當查找到對應的設備之后,我們需要獲取該設備配置空間的基本資源。

  DRV_CTRL * pDrvCtrl;

pDrvCtrl = calloc(1, sizeof(DRV_CTRL));

pDrvCtrl->pciBus = pciBus;

pDrvCtrl->pciDevice = pciDevice;

pDrvCtrl->pciFunc = pciFunc;


第一句是為該設備分配內存空間,其中DRV_CTRL的定義見“WindRiver驅動開發基礎”這篇文章。

要訪問pci設備空間有專門的訪問控制函數,這里我們使用:

pciConfigInLong():從pci配置空間指定位置讀取一個字長。

pciConfigInLong



int busNo,

int deviceNo,

int funcNo,

int offset,

UINT32 *pData


注:最后一個參數用於存放都會的數據

通過pciConfigInLong()函數我們需要獲取下面的幾個信息:IO地址,PCI設備地址,中斷號。並且需要映射內存,使能I/O

代碼如下:

   UINT32 membaseCsr;

UINT32 iobaseCsr;

UINT8 irq;

pciConfigInLong(pDrvCtrl->pciBus, pDrvCtrl->pciDevice, pDrvCtrl->pciFunc,PCI_CFG_BASE_ADDRESS_0, &iobaseCsr);

pciConfigInLong(pDrvCtrl->pciBus, pDrvCtrl->pciDevice, pDrvCtrl->pciFunc,PCI_CFG_BASE_ADDRESS_1, &membaseCsr);

pciConfigInByte(pDrvCtrl->pciBus, pDrvCtrl->pciDevice, pDrvCtrl->pciFunc,PCI_CFG_DEV_INT_LINE, &irq);

pciConfigOutWord(pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND,CI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE);

membaseCsr &=PCI_MEMBASE_MASK;
iobaseCsr &=PCI_IOBASE_MASK;

pDrvCtrl->membase = membaseCsr;

pDrvCtrl->iobase = iobaseCsr;

pDrvCtrl->created = 0;

pDrvCtrl->irq = irq;

/*為了便於后面使用IO地址將IO地址專門保存本起來*/

ioaddr = iobaseCsr;

 

 

至此pci設備的發現,設備空間的資源獲取就完成,接下來的任務是創建設備,注冊設備,與硬件通信等。

還需要注意的是WindRiver中不允許'//'類型的代碼注釋,如上面代碼中的注釋只能使用'/**/'。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM