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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux PCI设备驱动

發布時間:2024/1/1 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux PCI设备驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 1.PCI 簡介

    • 1.1 PCI 引腳

    為處理數據、尋址、接口控制、仲裁以及系統功能,PC接口作為目標設備的設備至少有47條引腳。作為總線主設備的設備至少有49條引腳。必要的引腳在左邊,任選的引腳在右邊

    • 1.2 傳輸速率

    Transparent upgrade from 32-bit data path at 33 MHz
    (132 MB/s peak) to 64-bit data path at 33 MHz
    (264 MB/s peak) and from 32-bit data path at 66 MHz
    (264 MB/s peak) to 64-bit data path at 66 MHz
    (528 MB/s peak).

    • 1.3 PCI 的配置空間
      所有的PCI都設備必須實現PCI協議規定必需的配置寄存器,以便系統上電時利用這些寄存器的信息來進行系統配置。
      配置空間頭區域及功能:
  • 設備識別
  • 設備控制
  • 設備狀態
  • 基址寄存器。系統初始化代碼在引導操作系統之前,必須建立一個統一的地址映射關系,以確定系統中有多少存儲器和IO控制器,它們需要占用多少地址空間,當確定這些信息后,系統初始化代碼便可以吧IO控制器映射到合理的地址空間并引導系統。為了做到這種映射與相應設備無關,在配置空間頭區域中安排了一組供映射時使用的基址寄存器。

    基地址設置過程:

    查看pci 配置寄存器內容:# hexdump /sys/bus/pci/devices/xxx/xxx/config 0000000 8086 2e30 0006 2090 0003 0600 0000 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 1458 5000 0000030 0000 0000 00e0 0000 0000 0000 0000 0000 0000040 9001 fed1 0000 0000 4001 fed1 0000 0000 0000050 0000 0350 0009 0000 0000 0000 0000 0000 0000060 0005 e000 0000 0000 8001 fed1 0000 0000 0000070 0000 0000 0000 0000 0001 0000 0000 0000 0000080 0000 0000 0000 0000 0000 0000 0000 0000 0000090 1110 0011 0000 0000 03ff 0000 0a00 0079 00000a0 0020 0800 0000 7e00 0000 7de0 0000 7dd0 00000b0 8000 0000 0000 0000 0000 0000 0000 0000 00000c0 0000 0000 0000 0000 0000 0000 0000 0000 00000d0 0000 0000 0303 0000 6660 1366 aa55 aa55 00000e0 0009 610c 0b24 cfa7 9de2 812f 0000 0000 00000f0 0000 0000 0000 0000 0fa6 0005 0000 0000 0000100 0000 0000 0000 0000 0000 0000 0000 0000 * 0001000
  • 2.PCI 驅動

    • 2.1 注冊一個PCI設備驅動
      為了被正確注冊到內核, 所有的 PCI 驅動必須創建的主結構是 struct pci_driver 結構.
      這個結構包含許多函數回調和變量, 來描述 PCI 驅動給 PCI 核心. 這里是這個結構的一
      個 PCI 驅動需要知道的成員:
    struct pci_driver{ const char *name;/*驅動的名子. 它必須是唯一的, 在內核中所有 PCI 驅動里面. 通常被設置為和驅動模塊名子相同的名子. 它顯示在 sysfs 中在 /sys/bus/pci/drivers/ 下.*/ const struct pci_device_id *id_table;/*指向 struct pci_device_id 表的指針,用于macth函數*/ int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);/*指向 PCI 驅動中 probe 函數的指針*/ void (*remove) (struct pci_dev *dev);/*指向 PCI 核心在 struct pci_dev 被從系統中去除時調用的函數的指針*/ ... }

    總之, 為創建一個正確的 struct pci_driver 結構, 只有 4 個字段需要被初始化,一個PCI設備驅動的骨架如下:

    static int probe(struct pci_dev *dev, const struct pci_device_id *id) {//... } static void remove(struct pci_dev *dev) {//... } static struct pci_driver pci_driver = { .name = "pci_skel", .id_table = ids, .probe = probe, .remove = remove, }; static int __init pci_skel_init(void) {return pci_register_driver(&pci_driver); } static void __exit pci_skel_exit(void) {pci_unregister_driver(&pci_driver); } module_init(pci_skel_init); module_exit(pci_skel_exit);
    • 2.2 probe 函數
      pci_driver 的 probe()函數要完成 PCI 設備的初始化及其設備本身身份(字符、TTY、
      網絡等)驅動的注冊。
    //pci_driver probe()函數 的骨架 int probe(struct pci_dev *dev, const struct pci_device_id *id) {if (pci_enable_device(pdev)){return -EIO;}iobase = pci_resource_start(pdev, 0); //獲取io基地址 ,0 ~5 根據具體設備來定...request_region(iobase , size, "name"); // 申請io空間,聲明這塊地址空間已經被占用...dev_init(); // 注冊字符設備,網絡設備等,以及注冊中斷 }
    • 2.3 常用的接口
    申請/釋放 I/O 或內存資源。 int pci_request_regions(struct pci_dev *pdev, const char *res_name); void pci_release_regions(struct pci_dev *pdev); 獲取/設置驅動私有數據。 void *pci_get_drvdata(struct pci_dev *pdev); void pci_set_drvdata(struct pci_dev *pdev, void *data); 使能/禁止 PCI 設備。 int pci_enable_device(struct pci_dev *dev); void pci_disable_device(struct pci_dev *dev); 設置為總線主 DMA。 void pci_set_master(struct pci_dev *dev); 尋找指定總線指定槽位的 PCI 設備。 struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn); 設置 PCI 能量管理狀態(0=D0 ... 3=D3)。 int pci_set_power_state(struct pci_dev *dev, pci_power_t state); 在設備的能力表中找出指定的能力。 int pci_find_capability(struct pci_dev *dev, int cap); 啟用設備內存寫無效事務。 int pci_set_mwi(struct pci_dev *dev); 禁用設備內存寫無效事務。 void pci_clear_mwi(struct pci_dev *dev);
  • 3.小結
    就跟USB、I2C、SPI、UART等常用接口一樣,PCI 也是一種通信接口,其最終的目的是實現數據交換,如果一個SPI接口的外設模塊要接在PCI接口上實現數據通信,那么中間需要加一個轉換芯片,如TIGER320.
    PCI 設備的啟動分為兩個部分,第一部分是系統引導時,讀取配置寄存器信息(也就是常說的的配置空間)并確認好基址映射地址回寫到PCI設備的基址寄存器。第二部分是系統啟動后加載驅動,探測到該設備后,進行的初始化操作,如啟用PCI設備,申請IO空間,具體設備注冊,注冊中斷等。

參考資料:
1.《微機原理與接口技術》[劉立康]
2.《linux設備驅動程序》

總結

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

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