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

📄 spioc.c

📁 it is character driver
💻 C
字号:
/* spioc.c, 2006-06-02 * GS0521117 秦广  */#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <asm/hardware.h>#include <linux/delay.h>#include "spioc.h"#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <asm/hardware.h>#undef DEBUG#define DEBUG#ifdef DEBUG#define DPRINTK( x... )	printk("s3c2410-kbd: " ##x)#else#define DPRINTK( x... )#endif#define DEVICE_NAME		"spioc"#define KBDRAW_MINOR	1static int spioc_major = 0;#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_spioc;#endif  /**********************************************************************/DECLARE_WAIT_QUEUE_HEAD(spioc_queue);static void spioc_do_tasklet(unsigned long);DECLARE_TASKLET(spioc_tasklet,spioc_do_tasklet,0);/*do tasklet*/static void spioc_do_tasklet(unsigned long temp){	int i;	char p;  printk("tasklet is here.qinguang");                                                          for(i=0; i<count/2; i++)	{		 p=wbuff[i];     wbuff[i]= wbuff[count-i-1];         wbuff[count-i-1]=p;  }    	//唤醒中断	wake_up_interruptible(&spioc_queue);	return;}/*中断响应函数*/static void spioc_interrupt(int irq, void *dev_id, struct pt_regs *regs){	printk("kbd interrupt received.\n");	printk("here is call talklet_schedule,spioc_tasklet .jw\n");	tasklet_schedule(&spioc_tasklet);	return;}/* open and close */static int spioc_open(struct inode *inode, struct file *filp){  enable_irq(IRQ_EINT4);	memset(wbuff, 0, BUFFSIZE);	memset(rbuff, 0, BUFFSIZE);	count = 0;	//初始化中断	init_waitqueue_head(&spioc_queue);	MOD_INC_USE_COUNT;	DPRINTK( "opened\n");	return 0;	}static int spioc_close(struct inode *inode, struct file *filp){	MOD_DEC_USE_COUNT;	//禁止中断  disable_irq(IRQ_EINT4);	DPRINTK("closed\n");	return 0;}/* read and write */static ssize_t spioc_read(struct file *filp, char *buf, size_t cnt, 	loff_t *off){	int i;	printk("calling spioc_read(),interruptible_sleep_on.\n");  interruptible_sleep_on(&spioc_queue);  	if(signal_pending(current))		return -ERESTARTSYS;	if(!count)		return 0;	for(i=0; i<count; i++)		rbuff[i] = wbuff[i];	if(cnt > count)		cnt = count;	copy_to_user(buf, rbuff, cnt);	return cnt;}static ssize_t spioc_write(struct file *filp, const char *buf, size_t cnt, 	loff_t *off){ printk("Write to wbuff,Copy_from_user().\n");	if(cnt > BUFFSIZE)		cnt = BUFFSIZE;	copy_from_user(wbuff, buf, cnt);	count = cnt;	return cnt;}/* ioctl */static int spioc_ioctl(struct inode *inode, struct file *filp, 	unsigned int cmd, unsigned long arg){	switch(cmd) {	default:		break;	}	return 0;}/* the device fops */static struct file_operations spioc_fops = {	owner:		THIS_MODULE,	read:		spioc_read,	write:		spioc_write,	ioctl:		spioc_ioctl,	open:		spioc_open,	release:	spioc_close,};/* init and exit */static int __init spioc_init(void){    int ret;	int flags;		int result;    int result_irq;	wbuff = kmalloc(BUFFSIZE, GFP_KERNEL);	rbuff = kmalloc(BUFFSIZE, GFP_KERNEL);	ret = set_external_irq(IRQ_EINT4, EXT_FALLING_EDGE, GPIO_PULLUP_EN);	local_irq_save(flags);	DPRINTK("system register=0x%x\n", ret);	result = register_chrdev(SPIOC_MAJOR, "spioc", &spioc_fops);	if(result < 0) {		printk(KERN_ERR "Cannot register spioc device.\n");		kfree(wbuff);		kfree(rbuff);		return -EIO;	}    result_irq = request_irq(IRQ_EINT4, spioc_interrupt,SA_INTERRUPT, "spioc",spioc_interrupt);	if(result_irq) {		printk("spioc: irq request failed.\n");		}#ifdef CONFIG_DEVFS_FS    result = devfs_register_chrdev(0,DEVICE_NAME, &spioc_fops);	if(result < 0) return result;	spioc_major = result;	devfs_spioc = devfs_register(NULL, "spioc", DEVFS_FL_DEFAULT,				spioc_major, KBDRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &spioc_fops, NULL);#endif	printk (DEVICE_NAME"\tinitialized\n");	return 0;}static void __exit spioc_exit(void){	int result;#ifdef CONFIG_DEVFS_FS		devfs_unregister(devfs_spioc);#endif	unregister_chrdev(spioc_major, DEVICE_NAME);	result = unregister_chrdev(SPIOC_MAJOR, "spioc");	if(result < 0) {		printk(KERN_ERR "Cannot remove spioc device.\n");		return;	}    free_irq(IRQ_EINT4,NULL);	if(wbuff)		kfree(wbuff);	if(rbuff)		kfree(rbuff);	return;}module_init(spioc_init);module_exit(spioc_exit);

⌨️ 快捷键说明

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