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

📄 trlight.c

📁 中科院徐志伟老师一书《操作系统 原理·技术与编程》的源代码和习题接
💻 C
字号:
#include <linux/kernel.h>#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/types.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/tqueue.h>#include <linux/ctype.h>#include <asm/segment.h>#include <asm/io.h>#include <asm/uaccess.h>#include "ring.h"#include "trlight.h"#define ADDRRANGE 3static int trlight_major = 99;static int base=0x378;ring_buf write_buf;static int write_open = 0;static int read_open =0;    int traffic_setval = 0;int traffic_delay = 120;unsigned short word =3;static int tick_counter = 0;static void timer_handler(void *);static struct tq_struct time_queue_entry = { 			routine:timer_handler,		};int queue_flag=1; static DECLARE_WAIT_QUEUE_HEAD(tick_wait);void turn_on_off(){	if(word!=0)		word=~word;	outw((word & 0x00FF),base+0);	}void start(){	word=3;}void stop(){	word=0;}static void bottom_half(){	tick_counter++;	if (ring_buf_read(&write_buf, &traffic_setval)==1)	{		traffic_delay=traffic_setval;	}	if(traffic_delay<=tick_counter)	{			tick_counter=0;		turn_on_off();	}	if(queue_flag==1)		queue_task(&time_queue_entry,&tq_timer);	else wake_up(&tick_wait);	}	static void timer_handler(void *tick){	bottom_half();}static int trlight_read(struct file *fp,char *buf, size_t count, loff_t* pos);static int trlight_write(struct file* fp, const char *buf,size_t count, loff_t* pos);static int trlight_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);static int trlight_open(struct inode *inode,struct file *file);static int trlight_release(struct inode *inode,struct file *file);	static struct file_operations trlight_fops = {	THIS_MODULE,		/*module owner*/	NULL,                   /* lseek */  	trlight_read,           /* read */	trlight_write,          /* write */	NULL,                   /* readdir */	NULL,                   /* select */	trlight_ioctl,          /* ioctl */	NULL,                   /* mmap */	trlight_open,           /* open */	NULL,	trlight_release,        /* close */	NULL,                   /* fsync */	NULL,                   /* fasync */	NULL,	NULL,	NULL,	NULL,	NULL,};static int trlight_read(struct file *fp,char *buf, size_t count, loff_t* pos){	int len; 	char kbuf[64];		sprintf(kbuf,"delay=%d\n",traffic_delay);	len=strlen(kbuf)+1;	len=len<count?len:count;	if(verify_area(VERIFY_WRITE,buf,len) < 0){	   printk("trlight_read:verify area failed\n");	   return(-1);	}	copy_to_user(buf,kbuf,len);	return len;}  static int trlight_write(struct file* fp, const char *buf,size_t count, loff_t* pos){	static int counter=0;	int *value; 	static char local[sizeof(int)];	int ret;	if(!write_open){		printk("trlight:ERROR: not open for writing\n");		return -1;	}	if((verify_area(VERIFY_READ,buf,count)) < 0){		printk("trlight_write:verify area failed\n");		return(-1);	}	if(counter<sizeof(int)-1){		copy_from_user(local+counter,buf,1);		counter++;		return 1;	}	else if(counter==sizeof(int)-1){		counter=0;		value=(int*)local;		if(*value<0)		{			printk("trlight:ERROR: invalid value\n");			return -1;		}		ret = ring_buf_write(&write_buf,*value);					if(ret==1)			return 1;		else 	return -1;	     }else	return -1;}static int trlight_ioctl(struct inode *inode,struct file *file,unsigned int cmd, unsigned long arg){	if (cmd==TRLIGHT_STOP)	{		printk("in stop\n");		stop();		return 0;	}	if (cmd==TRLIGHT_START)	{		printk("in start\n");		start();		return 0;	}	return -1;}static int trlight_open(struct inode *inode,struct file *file){	printk("trlight:trlight_open()-file->f_mode=%d\n",file->f_mode);	if(file->f_mode == 1){   /* read */		if(write_open){			printk("trlight:trlight_open()- write busy\n");                        return(-EBUSY);                }		MOD_INC_USE_COUNT;		read_open++;	}else{ 		if(file->f_mode == 2){  /* write */			if(write_open){				printk("trlight:trlight_open()- write busy\n");				return(-EBUSY);			}else{				if(read_open>0){					printk("trlight:trlight_open()- read busy\n");					return(-EBUSY);				}				write_open = 1;				MOD_INC_USE_COUNT;			}		}else{			printk("trlight:trlight_open()-unknown mode\n");			return(-EINVAL);	    	}	}	return 0;}int trlight_release(struct inode *inode,struct file *file){	if(file->f_mode == 1){   /* read */		MOD_DEC_USE_COUNT;		read_open--;	}else if(file->f_mode ==2){  /* write */			if(write_open){				write_open = 0;				MOD_DEC_USE_COUNT;			}else{			       printk("trlight:no write device to close-ERROR\n");   				       return -1;			}		}else{			printk("trlight:trlight_release()-unknown mode\n");   			return -1;		}	return 0;}int init_module(void){	int major;	ring_buf_init(&write_buf);	if((major = register_chrdev(trlight_major,"trlight",&trlight_fops))<0){		printk("trlight:unable to get major device\n");		return(-EIO);	}	printk("trlight:major number=%d\n",trlight_major);	if(check_region(base,ADDRRANGE)){		printk("trlight:port in use");		return -1;	}	request_region(base,ADDRRANGE,"trlight");	if(!queue_task(&time_queue_entry,&tq_timer))		return -1;	printk("trlight:module loaded\n");	return(0);}	void cleanup_module(void){	release_region(base,ADDRRANGE);	if(MOD_IN_USE){		printk("trlight:device busy, del delayed\n");		return;	}		printk("unregister_chrdev(%d,%s)\n",trlight_major,"trlight");	if(unregister_chrdev(trlight_major,"trlight")!=0){		printk("trlight: unregister_chrdev() failed.\n");		printk("trlight:/proc/devices will cause core dumps\n");	}	if(queue_flag){		queue_flag=0;		sleep_on(&tick_wait);	}	printk("trlight:module unloaded\n");}

⌨️ 快捷键说明

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