微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Linux驱动程序开发:PCI和PCIe驱动程序之间的区别?

我正在为Linux 2.6.36编写一个PCI驱动程序。

这是我的代码。 我的问题是,如果我想使用此驱动程序的PCIe设备,我必须做一些修改

#include <linux/fs.h> #include <linux/module.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <asm-generic/signal.h> #undef debug // ATTENTION copied from /uboot_for_mpc/arch/powerpc/include/asm/signal.h // Maybe it don't work with that //____________________________________________________________ #define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ #define SA_SHIRQ 0x04000000 //____________________________________________________________ #define pci_module_init pci_register_driver // function is obsoleted // Hardware specific part #define MY_vendOR_ID 0x5333 #define MY_DEVICE_ID 0x8e40 #define MAJOR_NR 240 #define DRIVER_NAME "PCI-Driver" static unsigned long ioport=0L,iolen=0L,memstart=0L,memlen=0L,flag0,flag1,flag2,temp=0L; // private_data struct _instance_data { int counter; // just as a example (5-27) // other instance specific data }; // Interrupt Service Routine static irqreturn_t pci_isr( int irq,void *dev_id,struct pt_regs *regs ) { return IRQ_HANDLED; } // Check if this driver is for the new device static int device_init(struct pci_dev *dev,const struct pci_device_id *id) { int err=0; // temp variable #ifdef debug flag0=pci_resource_flags(dev,0 ); flag1=pci_resource_flags(dev,1 ); flag2=pci_resource_flags(dev,2 ); printk("DEBUG: FLAGS0 = %un",flag0); printk("DEBUG: FLAGS1 = %un",flag1); printk("DEBUG: FLAGS2 = %un",flag2); /* * The following sequence checks if the resource is in the * IO / Storage / Interrupt / DMA address space * and prints the result in the dmesg log */ if(pci_resource_flags(dev,0) & IORESOURCE_IO) { // Ressource is in the IO address space printk("DEBUG: IORESOURCE_IOn"); } else if (pci_resource_flags(dev,0) & IORESOURCE_MEM) { // Resource is in the Storage address space printk("DEBUG: IORESOURCE_MEMn"); } else if (pci_resource_flags(dev,0) & IORESOURCE_IRQ) { // Resource is in the IRQ address space printk("DEBUG: IORESOURCE_IRQn"); } else if (pci_resource_flags(dev,0) & IORESOURCE_DMA) { // Resource is in the DMA address space printk("DEBUG: IORESOURCE_DMAn"); } else { printk("DEBUG: nothingn"); } #endif /* debug */ // allocate memory_region memstart = pci_resource_start( dev,0 ); memlen = pci_resource_len( dev,0 ); if( request_mem_region( memstart,memlen,dev->dev.kobj.name )==NULL ) { printk(KERN_ERR "Memory address conflict for device "%s"n",dev->dev.kobj.name); return -EIO; } // allocate a interrupt if(request_irq(dev->irq,pci_isr,SA_INTERRUPT|SA_SHIRQ,"pci_drv",dev)) { printk( KERN_ERR "pci_drv: IRQ %d not free.n",dev->irq ); } else { err=pci_enable_device( dev ); if(err==0) // enable device successful { return 0; } else // enable device not successful { return err; } } // cleanup_mem release_mem_region( memstart,memlen ); return -EIO; } // Function for deinitialization of the device static void device_deinit( struct pci_dev *pdev ) { free_irq( pdev->irq,pdev ); if( memstart ) release_mem_region( memstart,memlen ); } static struct file_operations pci_fops; static struct pci_device_id pci_drv_tbl[] __devinitdata = { { MY_vendOR_ID,// manufacturer identifier MY_DEVICE_ID,// device identifier PCI_ANY_ID,// subsystem manufacturer identifier PCI_ANY_ID,// subsystem device identifier 0,// device class 0,// mask for device class 0 },// driver specific data { 0,} }; static int driver_open( struct inode *geraetedatei,struct file *instance ) { struct _instance_data *iptr; iptr = (struct _instance_data *)kmalloc(sizeof(struct _instance_data),GFP_KERNEL); if( iptr==0 ) { printk("not enough kernel memn"); return -ENOMEM; } /* replace the following line with your instructions */ iptr->counter= strlen("Hello Worldn")+1; // just as a example (5-27) instance->private_data = (void *)iptr; return 0; } static void driver_close( struct file *instance ) { if( instance->private_data ) kfree( instance->private_data ); } static struct pci_driver pci_drv = { .name= "pci_drv",.id_table= pci_drv_tbl,.probe= device_init,.remove= device_deinit,}; static int __init pci_drv_init(void) { // register the driver by the OS if(register_chrdev(MAJOR_NR,DRIVER_NAME,&pci_fops)==0) { if(pci_module_init(&pci_drv) == 0 ) // register by the subsystem return 0; unregister_chrdev(MAJOR_NR,DRIVER_NAME); // unregister if no subsystem support } return -EIO; } static void __exit pci_drv_exit(void) { pci_unregister_driver( &pci_drv ); unregister_chrdev(MAJOR_NR,DRIVER_NAME); } module_init(pci_drv_init); module_exit(pci_drv_exit); MODULE_LICENSE("GPL");

在linux上检测绑定挂载

如何在一个窗口中embeddedWebKit?

如何创build一个仅在pthread链接时才使用互斥体的库?

预加载audio缓冲区 – 什么是合理可靠的?

即使使用`noexecstack`,堆栈也是可执行的

什么导致模糊的符号错误? C ++

Windows窗体.net框架中的位移控件

为什么Linux中的内存使用量超过物理内存?

微软怎么能说WinAPI中一个单词的大小是16位?

构造函数/析构函数链接错误

从软件角度看,PCI和PCI Express设备基本相同。 PCIe设备具有相同的配置空间,BAR和(通常)支持相同的PCI INTx中断。

示例1:Windows XP对PCIe没有特殊的了解,但在PCIe系统上运行良好。

示例2:我公司提供PCI和PCIe版本的外设板,并使用相同的Windows / Linux驱动程序包。 司机不会“知道”两板之间的区别。

但是,PCIe设备频繁使用“高级”功能,如MSI ,Hotplugging,扩展配置空间等。许多这些功能都存在于传统PCI上,但未被使用。 如果这是您正在设计的设备,则无论您是否实施这些高级功能,都取决于您。

据我所知,对于我写的设备驱动程序,PCI设备和PCIe设备没有区别。 我的设备驱动程序使用和你一样的调用: chrdev , pci_resource , irq和mem_region 。

PCIe是具有更高速度和功能的高级版本。 所有标准的基本功能都保持不变。 驱动程序注册和提供处理程序是一回事,因为所有PCI驱动程序都注册到相同的Linux PCI子系统。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐