kernel-2.6.38内核驱动globalmem--添加中断机制和udev机制

来源:互联网 发布:手机打开docx软件 编辑:程序博客网 时间:2024/05/01 19:48
//这个驱动网上有例子,但是很多机制在新的内核里面已经过时了,所以我重写了一下,尽量使用了一些最近内核里面的机制。//创建设备节点,使用的udev机制;//注册中断向量的时候使用了新的接口函数,包括了ISR的接口的改变。#include <linux/module.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/cdev.h>#include <linux/device.h>//使用中断机制添加头文件#include <linux/sched.h>#include <asm/signal.h>#include <linux/interrupt.h>//使用udev机制添加的头文件#include <linux/slab.h>#ifdef CONFIG_SLUB#include <linux/slub_def.h>#elif defined CONFIG_SLOB#include <linux/slob_def.h>#else#include <linux/slab_def.h>#endif#include <asm/io.h>#include <asm/system.h>#include <asm/uaccess.h>//swliao:memory size 4K.#define MEMS_SIZE 0x1000 //#define MEMS_CLEAR 0x1#define MEMS_MAJOR 300static struct class *my_class;static int mems_major = MEMS_MAJOR;static unsigned int mems_irq = 1;static char* interface = "mems-test";//module_param()添加模块支持参数,每行设置一个参数module_param(mems_irq,int,S_IRUGO);module_param(interface,charp,S_IRUGO);//声明设备结构体struct mems_dev{struct cdev cdev;unsigned char mems[MEMS_SIZE];};struct mems_dev *mems_devp;//对应的中断向量的ISRstatic irqreturn_t mems_irq_handler(int irq,void *dev_id){printk(KERN_INFO "Interrupt handler...............................%d\n",irq);return IRQ_HANDLED;}//swliao:open function in file_operation.int mems_open(struct inode *inode,struct file *filp){filp->private_data = mems_devp;return 0;}//close()int mems_release(struct inode *inode,struct file *filp){return 0;}//swliao:read() function in file_operations.static ssize_t mems_read(struct file *filp,char __user *buf,size_t size,loff_t *ppos){unsigned long p =*ppos;unsigned int count = size;int ret = 0;struct mems_dev *dev = filp->private_data;if(p >= MEMS_SIZE)return count ? -ENXIO : 0;if(count > MEMS_SIZE-p)count = MEMS_SIZE - p;if(copy_to_user(buf,(void *)(dev->mems + p),count)){ret = -EFAULT;}else{*ppos += count;ret = count;printk(KERN_INFO "Liaosw read %d bytes.\n",count);}return ret;}static ssize_t mems_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos){unsigned long p = *ppos;unsigned int count = size;int ret = 0;struct mems_dev *dev = filp->private_data;if(p >= MEMS_SIZE)return count ? -ENXIO : 0;if(count > MEMS_SIZE -p)count = MEMS_SIZE - p;if(copy_from_user(dev->mems+p,buf,count)){ret = -EFAULT;}else{*ppos += count;ret = count;printk(KERN_INFO "Liaosw written %d bytes.\n",count);}return ret;}//swliao:very important file_operations structure.//字符驱动的主体实现部分:对应设备文件的file_operations结构体static const struct file_operations mems_fops = {.owner = THIS_MODULE,.read = mems_read,.write = mems_write,.open = mems_open,.release = mems_release,};static void mems_setup_cdev(struct mems_dev *dev,int index){int devno = MKDEV(mems_major,index);cdev_init(&dev->cdev,&mems_fops);dev->cdev.owner = THIS_MODULE;dev->cdev.ops = &mems_fops;int err = cdev_add(&dev->cdev,devno,1);if(err)printk(KERN_NOTICE "Error %d addint cdev %d.\n",err,index);}//内核模块的入口函数//字符设备驱动程序三步:创建分配,初始化,安装注册int mems_init(){printk(KERN_INFO "Install the driver to kernel space.\n");int result = 0;dev_t devno = MKDEV(mems_major,0);if(mems_major)result = register_chrdev_region(devno,1,"mem-test");else{result = alloc_chrdev_region(&devno,0,1,"mem-test");mems_major = MAJOR(devno);}if(result < 0)return result;mems_devp = kmalloc(sizeof(struct mems_dev),GFP_KERNEL);if(!mems_devp){result = -ENOMEM;goto fail_malloc;}memset(mems_devp,0,sizeof(struct mems_dev));mems_setup_cdev(mems_devp,0);my_class = class_create(THIS_MODULE,"my_class");if(IS_ERR(my_class)){printk("Err:failed in creating class.\n");return -1;}device_create(my_class,NULL,MKDEV(mems_major,0),NULL,"mem-test",0);//register interrupt.        //请求分配中断向量        int flagnum;if(!(flagnum = request_irq(mems_irq,&mems_irq_handler,IRQF_SHARED,interface,mems_devp))){printk(KERN_INFO "Register interrupt correctly..\n");goto fail_malloc;}elseprintk(KERN_INFO "Error was happened here...%d\n",flagnum);return 0;fail_malloc:unregister_chrdev_region(devno,1);return result;}void mems_exit(){cdev_del(&mems_devp->cdev);        //udev的退出清理device_destroy(my_class,MKDEV(mems_major,0));class_destroy(my_class);kfree(mems_devp);        //释放设备号和中断向量free_irq(mems_irq,mems_devp);unregister_chrdev_region(MKDEV(mems_major,0),1);printk(KERN_INFO "Test module quit kernel space.\n");}MODULE_AUTHOR("LiaoSW");MODULE_LICENSE("GPL");module_init(mems_init);module_exit(mems_exit);希望对大家有帮助,转载请注明出处,谢谢。
原创粉丝点击