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

http://hi.baidu.com/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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值