日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

vxworks pci驱动

發布時間:2024/1/1 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vxworks pci驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PCI配置空間

當VxWorks內核起來之后,PCI設備的第一次使用都是必須在調用sysHwInit2()例程之后。但是由于MMU內存映射的初始化和激活是在例程sysHwInit()和sysHwInit2()之間的,所以推薦的PCI初始化順序為:

sysHwInit()?默認的MMU?table?entries相當于將本地事務映射為PCI事務的HOST-Bridge的訪問側

sysHwInit2()?在該例程中,程序員必須靜態配置所有的PCI設備,或者調用動態配置routine?pciAutoConfig()

每個PCI設備有3種物理空間:配置空間、存儲器空間和I/O空間。配置空間是長度256字節的一段連續空間(16個32位寄存器)其中前64個字節為頭標,其余192字節為設備相關信息。在64字節的頭標中,前16字節的定義是確定的,后48字節的具體含義因設備而異。配置空間中的一個重要部分是基地址寄存器(BaseAddresssRegister),它的內容是PCI設備的地址空間映射到系統地址空間的起始物理地址。其中,bit0=1表示IO空間映射,bit0=0表示存儲器空間映射。所有PCI設備必須實現存儲器空間映射。通過向BAR寫全1即可確定所需地址空間的大小。在VxWorks下要訪問一個PCI設備,只需要知道該設備的廠商號和設備號。

基于VxWorks的PCi設備驅動程序開發流程,分為4個步驟:①創建設備;②根據PCI設備的配置參數,對PCI設備編寫功能函數程序;

知道廠商號和設備號后,利用VxWorks提供的函數pciFindDevice()獲得設備的總線號、設備編號和功能號。然后調用peiConfigInLong()獲得多功能數據采集卡設備的配置空間、內存空間、I/O空間的地址;pciConfigInByte得到設備中斷號。在讀取設備的基地址時,結合設備相關的說明書進行。

STATUS?pciFindDevice(int?vendorId,?int?deviceId,int?index,int?*pBusNo,int?*pDeviceNo,int?*pFuncNo)

注意第三個參數?‘index’該類PCI設備的索引號,這是在系統中有多個pci設備時我們需要從0開始查找,直到查找到我們想要驅動設備(第一個參數vendorId和第二個參數deviceId相同的設備)。

后面三個參數就是唯一標識該pci設備的資源參數,也是我們在查找pci設備的時候需要獲得該設備空間中的pci設備資源。

由于使用的是PENTIUM系列的CPU來進行板卡驅動的開發,所以在邊接中斷向量的時候,中斷號要加上0x20。

在系統配置PCI設備完畢后,必須首先訪問PCI配置空間獲取相關的信息并傳遞給Device?Driver。因為BIOS在掃描PCI?BUS的過程中,會自動給BUS編號。例如某個設備的編號為(250)可能會由于通過PCI-PCI橋來擴展或者移除PCI設備而變為(150)。在正常的設備操作過程中,不應該去訪問PCI的配置空間。


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

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

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

pciConfigInLong(int?busNo,int?deviceNo,int?funcNo,int?offset,UINT32?*pData)

注:最后一個參數用于存放返會的數據

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

當將PCI設備空間的資源映射出來之后,PCI設備的基本框架就建立起來了。

首先注冊驅動程序,調用:

int?iosDrvInstall()?/?STATUS?iosDevAdd()

Int?iosDrvInstall(FUNCPTR??pCreate,???FUNCPTR??pDelete,FUNCPTR??pOpen,????FUNCPTR??pClose,FUNCPTR??pRead,????FUNCPTR??pWrite,FUNCPTR??pIoctl?)除了最后一個參數之外,其它參數都可以為NULL,最后一個參數向系統注冊一個應用程序與驅動通信的函數。

一般需要進行寄存器的寫入或者讀出,我們會用到下面的函數:

sysInLong(int?port) 用于從寄存器讀出數據,其中的參數為寄存器的地址。?
? ? ? ?sysOutLong(int?port,?long?data)用于向寄存器port中寫入數據data

但是請注意:sysInLong?(),sysOutLong()函數中的port參數雖然都代表寄存器地址,但不能直接使用芯片手冊提供的地址,需要加一個設備基址“ioaddr”,這個地址是PCI設備空間的io基址。

調用驅動添加函數:

iosDevAdd(&pDrvCtrl?->pFCcardHdr,?name,?drvNum);

其中第一個參數是設備抽象中的第一個參數,也就是內核中的數據結構:DEV_HDR(pDrvCtrl參見前面的文章);第二個參數是我們為設備取的名字,也就是一個字符串;第三個參數為iosDrvInstall()函數的返回值。因此我們需要先調用iosDrvInstall()函數,再調用iosDevAdd函數。


pciConfigLib.c的標準庫給用戶訪問PCI配置空間.

3、PCI?Interrupt?Handling

每個PCI設備都有4個可用的中斷PIN,分別命名為A,B,C和D。每個單功能的PCI設備都被要求使用中斷PIN?A來產生中斷,而對于多功能PCI設備,每個功能使用一個中斷PIN,但是根據PCI規范,每個PCI設備最多可提供8個功能,這樣就必須兩個功能共用一個中斷PIN。當產生PCI中斷時,PCI中斷處理系統需要調用多個中斷服務程序,那么最簡單的方法就是每個ISR都調用一遍,ISR必須有能力判斷該次中斷源是否是自己產生的,如果不是,則立即返回,并接著會調用下一個中斷服務程序。pciIntLib.c提供一些routine來掛接多個ISR到一個中斷LINE上,該庫通過掛接一個特殊的ISR,該ISR會遍歷一個中斷鏈表,所有共用同一個中斷的ISRs都被放在這個鏈表中。pciIntConnect()用于將設備的ISR掛接到中斷鏈表上,而pciIntDisConnect()用于刪除中斷鏈表上的一個ISR

例子:

pciInitConnect(Vector,?ISR1,?PARAM1);

pciInitConnect(Vector,?ISR2,?PARAM2);

pciInitConnect(Vector,?ISR3,?PARAM3);

上面3個語句把ISR1,ISR2,和ISR3分別掛接到中斷向量為Vector的鏈表intList里面,那么當中斷發生時,會執行下面一個函數:

void?sISR(void)

{

while(intList->next?!=NULL)

(*intList->INT_ISR)(PARAM);/*分別調用ISR1,ISR2,ISR3*/

}

總結

以上是生活随笔為你收集整理的vxworks pci驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。