200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > linux系统PCI转串口驱动方法 【转】我的Linux PCI驱动程序

linux系统PCI转串口驱动方法 【转】我的Linux PCI驱动程序

时间:2019-03-06 07:33:35

相关推荐

linux系统PCI转串口驱动方法 【转】我的Linux PCI驱动程序

/fighter0425/blog/item/269a3bca3bed5649b219a8cb.html

这是一个完整的Linux PCI驱动程序了,自己写的,而且可用。

当初领命编写驱动程序的时候,在网上搜索Linux设备驱动,却找不到一个现成的(不过抄袭也不是好事……)。现在索性把这贡献出来,希望给看到的人一点帮助。

至于其他的参考资料嘛,确实LDD这本书是很有帮助的,建议多读一读。

/*mypci.c*/

#include

#include

#include

#include

#include

#include

#include

#include

//设备相关

#define MY_VENDOR_ID 0x1100

#define MY_DEVICE_ID 0x4258

#define MY_PCI_NAME "PCI-0x1100"

//端口读写变量

static int io;

static long range;

//中断申请

static int irq;

long tcount = 0;

/* 设备中断服务

*/

static void mypci_interrupt(int irq, void *dev_id, struct pt_regs *regs)

{

tcount ++;

return;

}

/* 探测PCI设备

*/

static int __init mypci_probe(struct pci_dev *dev, const struct pci_device_id *ent)

{

int retval, intport, intmask;

//启动设备

if ( pci_enable_device (dev) )

{

printk (KERN_ERR "IO Error.\n");

return -EIO;

}

//设定端口地址及其范围,指定中断IRQ

irq = dev->irq;

io = pci_resource_start(dev, 0);

range = pci_resource_end(dev, 0) - io;

printk ("PCI Driver at %X, and Interrupt %d.\n", io, irq);

//申请IO端口

if ( check_region(io, range) )

{

printfk (KERN_ERR "I/O %d is not free.\n", io);

return -1;

}

request_region (io, range, MY_PCI_NAME);

//申请中断IRQ并设定中断服务子函数

retval = request_irq (irq, mypci_interrupt, SA_INTERRUPT | SA_SHIRQ, MY_PCI_NAME, NULL);

if (retval)

{

printfk (KERN_ERR "Can't get assigned IRQ %d.\n", irq);

return -1;

}

printfk ("Request IRQ %d.\n", retval);

//硬件使能中断

intport = irq < 8 ? 0x21 : 0xa1;

intmask = inb_p (intport);

outb_p (intmask & ~( 0x01 << (irq & 0x07) ), intport);

outw_p (4000, io + 0x08);

return 0;

}

/* 移除PCI设备

*/

static void __devexit mypci_remove(struct pci_dev *dev)

{

free_irq (irq, NULL);

release_region (io, range);

return;

}

/* 指明驱动程序适用的PCI设备ID

*/

static struct pci_device_id mypci_table[] __initdata =

{

{

MY_VENDOR_ID,//厂商ID

MY_DEVICE_ID,//设备ID

PCI_ANY_ID,//子厂商ID

PCI_ANY_ID,//子设备ID

},

{0, },

};

MODULE_DEVICE_TABLE(pci, mypci_table);

/* 设备模块信息

*/

static struct pci_driver mypci_driver_ops =

{

name: MY_PCI_NAME,//设备模块名称

id_table: mypci_table,//驱动设备表

probe: mypci_probe,//查找并初始化设备

remove: mypci_remove//卸载设备模块

};

static int __init mypci_init(void)

{

//注册硬件驱动程序

if ( !pci_register_driver(&mypci_driver_ops) )

{

printk (KERN_ERR "Can't register driver!\n");

return -ENODEV;

}

printk ("The PCI driver is loaded successfully.\n");

mdelay (5000);

printk ("Time Count: %ld\n", tcount);

return 0;

}

static void __exit mypci_exit(void)

{

pci_unregister_driver(&mypci_driver_ops);

}

module_init(mypci_init);

module_exit(mypci_exit);

MODULE_LICENSE("GPL");

/*pci_include.mk*/

CFLAGS = -D__KERNEL__ -DMODULE -O2 -Wall -g

INCLUDE= -I/usr/src/linux-2.4.20/include

ARCH = i386

CC = gcc

/*Makefile*/

include pci_include.mk

mypci.o:mypci.c

$(CC) $(CFLAGS) $(INCLUDE) -c -o mypci.o mypci.c

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。