Chinaunix首页 | 论坛 | 博客
  • 博客访问: 87876
  • 博文数量: 22
  • 博客积分: 938
  • 博客等级: 准尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-16 21:27
文章存档

2010年(22)

我的朋友

分类: LINUX

2010-11-21 15:30:38

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/ctype.h>
#include <linux/cdev.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/uaccess.h>

MODULE_LICENSE("GPL");
#define COMMAND1 1
#define COMMAND2 2
struct DEMO_dev{
    struct cdev cdev ;
    char name [10];
}*DEMO_devp;



static dev_t DEMO_dev_number;
static unsigned char file_inc = 0;
static u8 demoBuffer[256];
struct class *DEMO_class;

#define DEVICE_NAME "DEMO"




static void __exit DEMO_cleanup(void){

    cdev_del(&DEMO_devp->cdev);

    device_destroy(DEMO_class,MKDEV( MAJOR(DEMO_dev_number),0));
    class_destroy(DEMO_class);

    printk("DEMO clean up\n");
    return ;
}
static int DEMO_open(struct inode *inode,struct file* file){
     struct DEMO_dev *dev;
     if(file_inc>0)
         return -ERESTARTSYS;
     file_inc ++;
     dev = container_of(inode->i_cdev,struct DEMO_dev,cdev);
     file->private_data = dev;
     return 0;
}

static int DEMO_release(struct inode *inode,struct file *fp){
    file_inc--;
    return 0;
}

static ssize_t DEMO_read(struct file *fp, char __user *buf, size_t count, loff_t *f_pos){
    loff_t pos = *f_pos;
    if(pos >= 256){
        return 0;
    }
    if(count > (256-pos)){
        count = 256 - pos;
    }
    pos += count;

    if(copy_to_user(buf,demoBuffer+*f_pos,count)){
        count=-EFAULT;
        return count;
    }
    *f_pos = pos;
    return count;
}
static ssize_t DEMO_write(struct file *fp,const char __user *buf,
        size_t count, loff_t *f_pos){
    size_t retval = -ENOMEM;
    loff_t pos = *f_pos;

    if(pos>=256){
        return retval;
    }
    if(count>(256-pos)){
        count=256-pos;
    }
    pos+=count;

    if(copy_from_user(demoBuffer+*f_pos, buf, count)){
        retval = -EFAULT;
        return retval;
    }
    *f_pos=pos;
    return count;
}

loff_t DEMO_llseek(struct file* fp,loff_t off, int where){
    loff_t pos;
    pos=fp->f_pos;
    switch(where){
        case 0: pos = off;
                break;
        case 1: pos+=off;
                break;
        case 2:
        default: return -EINVAL;
    }
    if((pos>256)||(pos<0)){
        return -EINVAL;
    }
    return fp->f_pos=pos;
}
int DEMO_ioctl(struct inode* inode, struct file *fp,
        unsigned int cmd, unsigned long arg){
    if(cmd==COMMAND1){
        printk("ioctl command1 trigger\n");
        return 0;
    }
    if(cmd== COMMAND2){
        printk("ioctl command2 trigger\n");
    }
    printk("ioctl error\n");
    return -EFAULT;
}
static struct file_operations DEMO_fops = {
    .owner = THIS_MODULE,
    .open = DEMO_open,
    .release = DEMO_release,
    .read = DEMO_read,
    .write = DEMO_write,
    .llseek = DEMO_llseek,
    .ioctl = DEMO_ioctl,
};

static int __init DEMO_init(void){

    if(0 > alloc_chrdev_region(&DEMO_dev_number,0,1,DEVICE_NAME)){
        printk(KERN_DEBUG"Can't register device\n");
        return -1;
    }

    DEMO_class = class_create(THIS_MODULE,DEVICE_NAME);


    DEMO_devp = kmalloc(sizeof(struct DEMO_dev),GFP_KERNEL);
    if(!DEMO_devp){
        printk("Bad Kmalloc\n");
        return -ENOMEM;
    }

    sprintf(DEMO_devp->name,"DEMO");

    cdev_init(&DEMO_devp->cdev,&DEMO_fops);

    DEMO_devp->cdev.owner = THIS_MODULE;
    DEMO_devp->cdev.ops = &DEMO_fops;

    if(cdev_add(&DEMO_devp->cdev,DEMO_dev_number,1)){
        printk ("Bad cdev\n");
        return 1;
    }

    device_create(DEMO_class,NULL,DEMO_dev_number,NULL,"DEMO");

    printk("DEMO device initialized\n");
    return 0;
}
module_init(DEMO_init);
module_exit(DEMO_cleanup);





KLIB_BUILD = /lib/modules/`uname -r`/build
MAKE = make
CC = gcc
AS = as
PWD = $(shell pwd)
obj-m += cmos.o
all:modules
modules:
    $(MAKE) -C $(KLIB_BUILD) M=$(PWD) modules
clean:
    rm *.o *.ko *.order *.symvers



#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
int main(){
    int fd;
    int i;
    char data[256];

    int retval;
    fd = open("/dev/DEMO",O_RDWR);
    if(1==fd){
        printf("error open\n");
        return -1;
    }
    retval = ioctl(fd,1,0);
    retval = write(fd,"hello world\n",13);
   if(retval == EFAULT){
        printf("write to file error\n");
    }
    printf("%d bytes write to file \n",retval);
    lseek(fd,0,0);
    retval = read(fd,data,13);
    data[retval]='\0';
    printf("%s\n",data);
    close(fd);
    return 0;
}


阅读(1093) | 评论(0) | 转发(0) |
0

上一篇:用2.95.3编译VIVI

下一篇:Makefile学习

给主人留下些什么吧!~~