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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

pci驱动与硬件通信

發(fā)布時(shí)間:2025/3/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pci驱动与硬件通信 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

接上一篇博文,當(dāng)將PCI設(shè)備空間的資源映射出來(lái)之后。只需要做兩件事情,PCI設(shè)備的基本框架就建立起來(lái)了。

首先注冊(cè)驅(qū)動(dòng)程序,調(diào)用如下函數(shù):

int iosDrvInstall() / STATUS iosDevAdd()

先來(lái)講int iosDrvInstall()函數(shù):

Int iosDrvInstall

(

FUNCPTR pCreate, FUNCPTR pDelete,

FUNCPTR pOpen, FUNCPTR pClose,

FUNCPTR pRead, FUNCPTR pWrite,

FUNCPTR pIoctl /*pointer to driver ioctl function*/

)


前面的文章已經(jīng)提到過(guò)。除了最后一個(gè)參數(shù)之外,其它參數(shù)都可以為NULL,最后一個(gè)參數(shù)向系統(tǒng)注冊(cè)一個(gè)應(yīng)用程序與驅(qū)動(dòng)通信的函數(shù)。應(yīng)用程序通過(guò)調(diào)用

ioctl

(

int fd,

int request,

void *data

);


三個(gè)參數(shù)分別代表文件描述符,請(qǐng)求操作碼和需要傳往驅(qū)動(dòng)的數(shù)據(jù)。

假設(shè)我們?cè)诤瘮?shù)iosDrvInstall()最后注冊(cè)的IOCtl函數(shù)為:pci_Ioctl()。

pci_Ioctl(int fd, int request, void *data)


注意:這里這個(gè)函數(shù)也需要包含三個(gè)參數(shù),與ioctl的參數(shù)對(duì)應(yīng),當(dāng)在應(yīng)用層調(diào)用ioctl()函數(shù)的時(shí)候,ioctl()中的第三個(gè)參數(shù)就會(huì)根據(jù)文件描述符來(lái)識(shí)別出正確的設(shè)備并將與驅(qū)動(dòng)通信的數(shù)據(jù)寫入到驅(qū)動(dòng)中的IOCTL函數(shù)中,這里是:pci_Ioctl()。

pci_Ioctl()函數(shù)的大體框架如下:

LOCAL STATUS pci_Ioctl(int DevID,int request, void *arg)

{



Switch(request)

{

case(X1):



break;

case(X2):



break

default:



}

return 1;

}


在每個(gè)分支針對(duì)傳進(jìn)來(lái)的操作碼進(jìn)行操作。操作碼一般是定義的宏,不同的操作我們定義一個(gè)不同的值來(lái)做標(biāo)識(shí)。

在case語(yǔ)句中一般需要進(jìn)行寄存器的寫入或者讀出,我們會(huì)用到下面的函數(shù):

sysInLong(int port)

sysOutLong(int port, long data)


其中sysInLong()函數(shù)用于從寄存器讀出數(shù)據(jù),其中的參數(shù)為寄存器的地址。

sysOutLong()函數(shù)用于向寄存器port中寫入數(shù)據(jù)data。

還記得上面的pci_Ioctl()函數(shù)嗎,這個(gè)函數(shù)中的第三個(gè)參數(shù)就是用于讀出或者寫入數(shù)據(jù)。為了實(shí)現(xiàn)讀出或者寫入并使的這些數(shù)據(jù)能輕松在應(yīng)用程序和驅(qū)動(dòng)之間傳遞,這個(gè)參數(shù)最好入上面一樣申明為void *。

但是請(qǐng)注意:sysInLong (),sysOutLong()函數(shù)中的port參數(shù)雖然都代表寄存器地址,但是不能直接使用芯片手冊(cè)或者是FPGA設(shè)計(jì)者提供的地址,需要加一個(gè)設(shè)備基址,也就是上一篇文章中提到的“ioaddr”,這個(gè)地址是PCI設(shè)備空間的io基址。因此這兩個(gè)讀入和寫入函數(shù)一般會(huì)進(jìn)行封裝,方便操作。

可以這樣做:

#define xxxDevice_Write(reg, value) sysOutLong(ioaddr+(reg), value)

#define xxxDevice_Read(reg) ((unsigned int) sysInLong(ioaddr+(reg)))

?

之后就可以直接調(diào)用這兩個(gè)宏,用于寫入或者讀出了。

?

現(xiàn)在可以介紹

iosDevAdd(DEV_HDR *pDevHdr, char *name, int drvnum)


了,我們可以這樣來(lái)調(diào)用該函數(shù):

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


其中第一個(gè)參數(shù)是設(shè)備抽象中的第一個(gè)參數(shù),也就是內(nèi)核中的數(shù)據(jù)結(jié)構(gòu):DEV_HDR(pDrvCtrl參見前面的文章);第二個(gè)參數(shù)是我們?yōu)樵O(shè)備取的名字,也就是一個(gè)字符串;第三個(gè)參數(shù)為iosDrvInstall()函數(shù)的返回值。因此我們需要先調(diào)用iosDrvInstall()函數(shù),再調(diào)用iosDevAdd函數(shù)。

經(jīng)過(guò)上面的介紹,驅(qū)動(dòng)的大體框架就建立好了。具體的操作就根據(jù)具體情況來(lái)進(jìn)行了。

本博客還會(huì)繼續(xù)介紹Windows下基于WDM的PCI設(shè)備驅(qū)動(dòng)程序開發(fā)和Linux下的PCI驅(qū)動(dòng)程序開發(fā)。如果有可能還會(huì)介紹Windows下WDF的PCI驅(qū)動(dòng)程序的開發(fā)。

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的pci驱动与硬件通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。