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裝置驅動與platform裝置驅動的對比學習 1 驅動模組結構 1 pcie裝置註冊 module pci driver x driver 展開之後對應於 module init x driver pci register drive x driver module exit x drive...
linux裝置驅動之PCIE驅動開發
pcie pci express 是intel提出的新一代的匯流排介面,目前普及的pcie 3.0的傳輸速率為8gt s,下一代pcie 4.0將翻番為16gt s,因為傳輸速率快廣泛應用於資料中心 雲計算 人工智慧 機器學習 視覺計算 顯示卡 儲存和網路等領域。pcie插槽是可以向下相容的,比如p...
PCIe總結 裝置資源
上篇文章說到列舉過程中的資源分配,這篇文章具體說下。首先要知道需要分配哪些資源,主要就2個 匯流排 bus 資源和記憶體 memory 資源。匯流排資源 bus資源就是給裝置分配唯一的id,其中bus號為8個bit,所以bus範圍為0 255,device是5個bit,所以範圍是0 31,funct...