linux裝置驅動之PCIE驅動開發

2021-10-23 12:20:58 字數 3647 閱讀 9315

pcie(pci express)是intel提出的新一代的匯流排介面,目前普及的pcie 3.0的傳輸速率為8gt/s,下一代pcie 4.0將翻番為16gt/s,因為傳輸速率快廣泛應用於資料中心、雲計算、人工智慧、機器學習、視覺計算、顯示卡、儲存和網路等領域。pcie插槽是可以向下相容的,比如pcie 1x介面可以插4x、8x、16x的插槽上。

實現基本的pcie驅動程式,實現以下模組:初始化裝置、裝置開啟、資料讀寫和控制、中斷處理、裝置釋放、裝置解除安裝。本程式適合pcie驅動開發通用除錯的基本框架,對於具體pcie裝置,需要配置相關暫存器才可以使用!

#include #include #include #include #include #include #include #include #include #include #include #include module_license("dual bsd/gpl");

module_description("pcie device driver");

#define dev_name "hello_pcie"

#define debug

#ifdef debug

#define debug_err(format,args...) \

dowhile(0)

#else

#define debug_print(format,args...)

#endif

//1m

#define dma_buffer_size 1*1024*1024

#define fasync_minor 1

#define fasync_major 244

#define device_number 1

static struct class * hello_class;

static struct device * hello_class_dev;

struct hello_device

my_device;

//barn(n=0,1,2或者0,1,2,3,4,5) 空間的實體地址,長度,虛擬位址

unsigned long bar0_phy;

unsigned long bar0_vir;

unsigned long bar0_length;

unsigned long bar1_phy;

unsigned long bar1_vir;

unsigned long bar1_length;

//進行dma轉換時,dma的源位址和目的位址

dma_addr_t dma_src_phy;

dma_addr_t dma_src_vir;

dma_addr_t dma_dst_phy;

dma_addr_t dma_dst_vir;

//根據裝置的id填寫,這裡假設廠商id和裝置id

#define hello_vendor_id 0x666

#define hello_device_id 0x999

static struct pci_device_id hello_ids = ,

};module_device_table(pci,hello_ids);

static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *id);

static void hello_remove(struct pci_dev *pdev);

static irqreturn_t hello_interrupt(int irq, void * dev);

//往iatu寫資料的函式

void iatu_write_config_dword(struct pci_dev *pdev,int offset,int value)

//假設需要將bar0對映到記憶體

static void iatu_bar0(void)

//往dma配置暫存器中讀寫資料的函式,這是難點一:dma暫存器的定址。

int dma_read_config_dword(struct pci_dev *pdev,int offset)

void dma_write_config_dword(struct pci_dev *pdev,int offset,int value)

void dma_init(void)

else

把資料暫存器的值寫入到dma的控制暫存器組中的 dma write channel 0 imwr data中

//dma_write_config_dword(my_device.pci_dev,dma write channel 0 imwr data,msi_data);

dma channel 0 control register 1 = 0x4000010

//dma_write_config_dword(my_device.pci_dev,dma channel 0 control register 1,0x4000010);

通道0 讀初始化 和上述操作類似,不再敘述。}

static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *id)

pci_set_master(pdev);

my_device.pci_dev=pdev;

if(unlikely(pci_request_regions(pdev,dev_name)))

//獲得bar0的實體地址和虛擬位址

bar0_phy = pci_resource_start(pdev,0);

if(bar0_phy<0)

//假設bar0是作為記憶體,流程是這樣的,但是在本程式中不對bar0進行任何操作。

bar0_length = pci_resource_len(pdev,0);

if(bar0_length!=0)

//申請一塊dma記憶體,作為源位址,在進行dma讀寫的時候會用到。

dma_src_vir=(dma_addr_t)pci_alloc_consistent(pdev,dma_buffer_size,&dma_src_phy);

if(dma_src_vir != 0)

result = request_irq(pdev->irq, hello_interrupt, 0, dev_name, my_device.pci_dev);

if (unlikely(result))

//dma 的讀寫初始化

dma_init();

enable_msi_error:

pci_disable_msi(pdev);

alloc_dma_dst_err:

for(i=0;iirq,my_device.pci_dev);

pci_disable_msi(pdev);

for(i=0;i程式執行後,在linux核心註冊pcie裝置,內容如下

pcie驅動開發(內含makefile,直接編譯即可使用)

linux下pcie裝置驅動

pcie裝置驅動與platform裝置驅動的對比學習 1 驅動模組結構 1 pcie裝置註冊 module pci driver x driver 展開之後對應於 module init x driver pci register drive x driver module exit x drive...

Linux驅動基礎 platform裝置驅動

以高通平台為例,會在kernel arch arm mach msm下的相應的board c檔案裡邊用 dt machine start 這個巨集定義一系列的晶元。以高通8916為例 在kernel arch arm mach msm board 8916.c檔案裡定義了 當然下面使用哪個要看一下。...

PCIe裝置驅動demo

pcie pci express 是intel提出的新一代的匯流排介面,目前普及的pcie 3.0的傳輸速率為8gt s,下一代pcie 4.0將翻番為16gt s,因為傳輸速率快廣泛應用於資料中心 雲計算 人工智慧 機器學習 視覺計算 顯示卡 儲存和網路等領域。pcie插槽是可以向下相容的,比如p...