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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

pci设备驱动例程

發(fā)布時(shí)間:2023/12/18 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pci设备驱动例程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
/*必須包含的兩個(gè)頭文件*/ #include <linux/module.h> #include <linux/pci.h>/*自定義結(jié)構(gòu)體,用在中斷服務(wù)函數(shù)里面*/ struct pci_Card {resource_size_t io; /*端口讀寫變量*/long range, flags; /*io地址范圍,標(biāo)志位*/void __iomem *ioaddr; /*io映射地址*/int irq; /*中斷號(hào)*/ };/*驅(qū)動(dòng)程序支持的設(shè)備列表,如果有匹配的設(shè)備,那么改驅(qū)動(dòng)程序就會(huì)被執(zhí)行*/ static struct pci_device_id ids[] = {{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, /*vendor id, 廠家ID*/0x100f) /*device id, 設(shè)備ID,可以通過(guò)lspci或者去相應(yīng)的目錄里面看*/},{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0) },{0,} /*最后一組為0,表示結(jié)束*/ };/*進(jìn)行注冊(cè),pci總線,ids為上面定義的設(shè)置*/ MODULE_DEVICE_TABLE(pci, ids);/*打印配置空間里面的一些信息*/ void skel_get_configs(struct pci_dev *dev) {uint8_t revisionId;uint16_t vendorId, deviceId;uint32_t classId;/*從參數(shù)dev里面也是可以打印vendorID等信息的,這個(gè)結(jié)構(gòu)體里面包含這個(gè)成員變量,用下面的API獲取得到的結(jié)果也是一致的*/pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId);printk("vendorID = %x", vendorId);pci_read_config_word(dev, PCI_DEVICE_ID, &deviceId);printk("deviceID = %x", deviceId);pci_read_config_byte(dev, PCI_REVISION_ID, &revisionId);printk("revisionID = %x",revisionId);pci_read_config_dword(dev, PCI_CLASS_REVISION, &classId);printk("classID = %x",classId); }/*設(shè)備中斷服務(wù)函數(shù)*/ static irqreturn_t pci_Mcard_interrupt(int irq, void *dev_id) {struct pci_Card *pci_Mcard = (struct pci_Card *)dev_id;/*中斷函數(shù)里面打印中斷號(hào)*/printk("irq = %d, pci_Mcard_irq = %d\n", irq, pci_Mcard->irq);return IRQ_HANDLED; }/*有匹配的設(shè)備,這個(gè)函數(shù)會(huì)執(zhí)行*/ static int probe(struct pci_dev *dev, const struct pci_device_id *id) {int retval = 0;struct pci_Card *pci_Mcard;printk("probe func\n"); /*設(shè)備使能*/if(pci_enable_device(dev)) {printk (KERN_ERR "IO Error.\n");return -EIO;}pci_Mcard = kmalloc(sizeof(struct pci_Card),GFP_KERNEL);if(!pci_Mcard) {printk("In %s,kmalloc err!",__func__);return -ENOMEM;}/*設(shè)備中斷號(hào)*/pci_Mcard->irq = dev->irq;if(pci_Mcard->irq < 0) {printk("IRQ is %d, it's invalid!\n",pci_Mcard->irq);goto out_pci_Mcard;}/*獲取io內(nèi)存相關(guān)信息*/pci_Mcard->io = pci_resource_start(dev, 0);pci_Mcard->range = pci_resource_end(dev, 0) - pci_Mcard->io + 1;pci_Mcard->flags = pci_resource_flags(dev,0);printk("start %llx %lx %lx\n",pci_Mcard->io, pci_Mcard->range, pci_Mcard->flags);printk("PCI base addr 0 is io%s.\n",(pci_Mcard->flags & IORESOURCE_MEM)? "mem":"port");/*防止地址訪問(wèn)沖突,所以這里先申請(qǐng)*/retval = pci_request_regions(dev,"pci_module");if(retval) {printk("PCI request regions err!\n");goto out_pci_Mcard;}/*再進(jìn)行映射*/pci_Mcard->ioaddr = pci_ioremap_bar(dev, 0);if(!pci_Mcard->ioaddr) {printk("ioremap err!\n");retval = -ENOMEM;goto out_regions;}/*申請(qǐng)中斷IRQ并設(shè)定中斷服務(wù)子函數(shù)*/retval = request_irq(pci_Mcard->irq, pci_Mcard_interrupt, IRQF_SHARED, "pci_module", pci_Mcard);if(retval) {printk (KERN_ERR "Can't get assigned IRQ %d.\n",pci_Mcard->irq);goto out_iounmap;}pci_set_drvdata(dev, pci_Mcard);skel_get_configs(dev);return 0;out_iounmap:iounmap(pci_Mcard->ioaddr); out_regions:pci_release_regions(dev); out_pci_Mcard:kfree(pci_Mcard);return retval; }/*移除PCI設(shè)備*/ static void remove(struct pci_dev *dev) {struct pci_Card *pci_Mcard = pci_get_drvdata(dev);free_irq (pci_Mcard->irq, pci_Mcard);iounmap(pci_Mcard->ioaddr);pci_release_regions(dev);kfree(pci_Mcard);pci_disable_device(dev);printk("remove pci device ok\n"); }/*結(jié)構(gòu)體成員變量填充*/ static struct pci_driver pci_driver = {.name = "pci_module",.id_table = ids,.probe = probe,.remove = remove, };/*模塊入口函數(shù)*/ static int __init pci_module_init(void) {printk("pci module entry function\n");return pci_register_driver(&pci_driver); }/*模塊退出函數(shù)*/ static void __exit pci_module_exit(void) {printk("pci module exit function\n");pci_unregister_driver(&pci_driver); }MODULE_LICENSE("GPL");module_init(pci_module_init); module_exit(pci_module_exit);

makefile

obj-m := pci_module.oKERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd)all:$(MAKE) -C $(KERNELDIR) M=$(PWD) clean:

執(zhí)行前先把e1000卸載了

sudo rmmod e1000

然后,執(zhí)行

sudo insmod pci_module.ko dmesg


參考:
1:https://www.kernel.org/doc/html/latest/PCI/pci.html
2:http://blog.chinaaet.com/justlxy/p/5100053251

總結(jié)

以上是生活随笔為你收集整理的pci设备驱动例程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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