Created
November 19, 2010 16:44
-
-
Save kerie/706745 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<linux/kernel.h> | |
#include<linux/module.h> | |
#include<linux/fs.h> | |
#include<linux/errno.h> | |
#include<linux/uaccess.h> | |
#include<linux/init.h> | |
#define RWBUF_SIZE 2048 | |
#define DEVICE_NAME "ChrDev" //修改为自己喜欢的名字 | |
#define RWBUF_CLEAR 0x909090 | |
#define RWBUF_LENGTH 0x808080 | |
#define RWBUF_NUM 0x707070 | |
//全局变量 | |
static char rwbuf[RWBUF_SIZE]="13081070"; //buffer 修改为自己的学号 | |
static int inuse = 0; //only one process is permited once | |
static int rwlen = 8; //the current length of buffer | |
static int writenum = 0; //the number of write | |
//函数向前声明 | |
static int rwbuf_open(struct inode *node, struct file *filep); | |
static int rwbuf_close(struct inode *node, struct file *filep); | |
static ssize_t rwbuf_write(struct file *filep, const char *buf, size_t count, loff_t *ppos); | |
static ssize_t rwbuf_read(struct file* filp, char *buf , size_t count, loff_t *ppos); | |
static int rwbuf_ioctl(struct inode *node, struct file * filep, unsigned int cmd, unsigned long arg); | |
//以下是2.6内核在文件操作结构的定义,老师给的是2.4的,编译通不过滴 | |
static struct file_operations rwbuf_fops = | |
{ | |
read: rwbuf_read, | |
write: rwbuf_write, | |
ioctl: rwbuf_ioctl, | |
open: rwbuf_open, | |
release: rwbuf_close, | |
}; | |
/******************************************* | |
init_module_rwbuf向系统的字符设备表登记了一个字符设备。 | |
老师ppt上说设备号在1~255之间,应该/proc/devices里面Character devices下没有被注册过的都可以,我测试过277也是可以的。 | |
******************************************/ | |
int init_module_rwbuf() | |
{ | |
register_chrdev(277,DEVICE_NAME,&rwbuf_fops); | |
printk(KERN_ALERT "register ok\n"); | |
return 0; | |
} | |
//cleanup_module_rwbuf释放字符设备在系统字符设备表中占有的表项。 | |
void cleanup_module_rwbuf() | |
{ | |
unregister_chrdev(277,DEVICE_NAME); | |
printk(KERN_ALERT "unreg ok\n"); | |
} | |
//inuse保证设备关闭前不能被多次打开 | |
static int rwbuf_open(struct inode *node, struct file *filep) | |
{ | |
if(inuse==1) | |
return -1; | |
inuse=1; | |
printk(KERN_ALERT "open ok\n"); | |
return 0; | |
} | |
static int rwbuf_close(struct inode *node, struct file *filep) | |
{ | |
inuse = 0; | |
printk(KERN_ALERT "close ok\n"); | |
return 0; | |
} | |
//设备支持每次写入字符不超过1024个,超过部分被丢弃 | |
static ssize_t rwbuf_write(struct file *filep, const char *buf, size_t count, loff_t *ppos) | |
{ | |
if(count<=1024) | |
{ | |
writenum++; | |
//printk(KERN_ALERT "write1\n"); | |
copy_from_user(rwbuf,buf,count); | |
//printk(KERN_ALERT "write2\n"); | |
rwlen = count; | |
//printk(KERN_ALERT "write ok\n"); | |
return rwlen; | |
} | |
else | |
{ | |
writenum++; | |
copy_from_user(rwbuf,buf,1024); | |
rwlen = 1024; | |
printk(KERN_ALERT "write overflow\n"); | |
return rwlen; | |
} | |
} | |
//用户可以读出最近写入到设备中的字符 | |
static ssize_t rwbuf_read(struct file* filp, char *buf , size_t count, loff_t *ppos) | |
{ | |
printk(KERN_ALERT "read\n"); | |
count=rwlen; | |
copy_to_user(buf,rwbuf,count); | |
printk(KERN_ALERT "read ok\n"); | |
return count; | |
} | |
//设备支持系统调用ioctl(int d, int req,…) | |
static int rwbuf_ioctl(struct inode *node, struct file * filep, unsigned int cmd, unsigned long arg) | |
{ | |
if(cmd==RWBUF_CLEAR) | |
{ | |
rwlen = 0; | |
printk(KERN_ALERT "rwbuf in kernel zero-ed\n"); | |
return 0; | |
} | |
else if(cmd==RWBUF_LENGTH) | |
{ | |
printk(KERN_ALERT "length of buffer\n"); | |
return rwlen; | |
} | |
else if(cmd==RWBUF_NUM) | |
{ | |
printk(KERN_ALERT "num of writing\n"); | |
return writenum; | |
} | |
return 0; | |
} | |
module_init(init_module_rwbuf); | |
module_exit(cleanup_module_rwbuf); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment