⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demo.c

📁 《linux驱动程序设计从入门到精通》一书中所有的程序代码含驱动和相应的应用程序
💻 C
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2007, 2010 fengGuojin(fgjnew@163.com) */#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/cdev.h>#include <linux/version.h>#include <linux/vmalloc.h>#include <linux/ctype.h>#include <linux/pagemap.h>#include "demo.h"MODULE_AUTHOR("fgj");MODULE_LICENSE("Dual BSD/GPL");struct DEMO_dev *DEMO_devices;static unsigned char demo_inc=0;static u8 demoBuffer[256];static struct work_struct task;static struct workqueue_struct *my_workqueue;static int flag = 0;static void DemoTask(void *p){        struct DEMO_dev *dev =(struct DEMO_dev *)p; 	flag = 1;	memset(demoBuffer,0x31,256);	wake_up_interruptible(&dev->wq); /* awake any reading process */}int DEMO_open(struct inode *inode, struct file *filp){	struct DEMO_dev *dev;	//if(demo_inc>0)return -ERESTARTSYS;	demo_inc++;	dev = container_of(inode->i_cdev, struct DEMO_dev, cdev);	filp->private_data = dev;	return 0;}int DEMO_release(struct inode *inode, struct file *filp){	demo_inc--;	return 0;}ssize_t DEMO_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos){	struct DEMO_dev *dev = filp->private_data; 		//等待数据可获得	if(wait_event_interruptible(dev->wq, flag != 0))	{		return - ERESTARTSYS;	}		flag = 0;	if (down_interruptible(&dev->sem))		return -ERESTARTSYS;		if (copy_to_user(buf,demoBuffer,count))	{	   count=-EFAULT; /* 把数据写到应用程序空间 */	   goto out;	}  out:	up(&dev->sem);	return count;}ssize_t DEMO_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos){	return 0;}int DEMO_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg){	  if(cmd==COMMAND1)	  {		   printk("ioctl command1 successfully\n");		   return 0;	  }	  if(cmd==COMMAND2)	  {		   printk("ioctl command2 successfully\n");		   return 0;	  }	 	  printk("ioctl error successfully\n");          return -EFAULT;}loff_t DEMO_llseek(struct file *filp, loff_t off, int whence){	return 0;}struct file_operations DEMO_fops = {	.owner =    THIS_MODULE,	.llseek =   DEMO_llseek,	.read =     DEMO_read,	.write =    DEMO_write,	.ioctl =    DEMO_ioctl,	.open =     DEMO_open,	.release =  DEMO_release,};/*******************************************************                MODULE ROUTINE*******************************************************/void DEMO_cleanup_module(void){	dev_t devno = MKDEV(DEMO_MAJOR, DEMO_MINOR);	if (DEMO_devices) 	{		cdev_del(&DEMO_devices->cdev);		kfree(DEMO_devices);	}	destroy_workqueue(my_workqueue);	unregister_chrdev_region(devno,1);}int DEMO_init_module(void){	int result;	dev_t dev = 0;	dev = MKDEV(DEMO_MAJOR, DEMO_MINOR);	result = register_chrdev_region(dev, 1, "DEMO");	if (result < 0) 	{		printk(KERN_WARNING "DEMO: can't get major %d\n", DEMO_MAJOR);		return result;	}	DEMO_devices = kmalloc(sizeof(struct DEMO_dev), GFP_KERNEL);	if (!DEMO_devices)	{		result = -ENOMEM;		goto fail;	}	memset(DEMO_devices, 0, sizeof(struct DEMO_dev));	init_MUTEX(&DEMO_devices->sem);	cdev_init(&DEMO_devices->cdev, &DEMO_fops);	DEMO_devices->cdev.owner = THIS_MODULE;	DEMO_devices->cdev.ops = &DEMO_fops;	result = cdev_add (&DEMO_devices->cdev, dev, 1);	if(result)	{		printk(KERN_NOTICE "Error %d adding DEMO\n", result);		goto fail;	}	init_waitqueue_head(&DEMO_devices->wq);		my_workqueue = create_workqueue("MYQUENU");	INIT_WORK(&task,DemoTask, DEMO_devices);	queue_work(my_workqueue, &task);	return 0;fail:	DEMO_cleanup_module();	return result;}module_init(DEMO_init_module);module_exit(DEMO_cleanup_module);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -