Cdev—每个次设备一个缓冲

-------------driver----------------

cdev.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <asm/uaccess.h>

MODULE_LICENSE("GPL");

dev_t devid;
char *name = "mychardev" ;
struct cdev cdev ;
struct file_operations ops;
struct class *cls ;
#define MINOR_NUM 3
#define GPECON 0x56000040

char * mybuff[MINOR_NUM]={NULL,NULL,NULL};
#define BUFFMAX 2048

unsigned int *gpecon,*gpedata ;

void mycdev_log(void)
{
    printk("hello_log");
   

}

int mychdev_open (struct inode * np, struct file * fp)
{
 //dev_t dev_id ;
// dev_id = MKDEV(imajor(np),iminor(np));
  fp->private_data = np ;
 
 if(mybuff[iminor(np)] == NULL)
     mybuff[iminor(np)] = (char *) kmalloc(BUFFMAX,GFP_KERNEL );
 
  printk("open mychdev =%d,%d=/n",imajor(np),iminor(np));
#if 0
  printk("open mychdev =%d,%d=/n",MAJOR(np->i_cdev->dev),MINOR(np->i_cdev->dev));
  printk("count =%d/n",np->i_cdev->count);   
 printk("open mychdev =%d,%d=/n",MAJOR(np->i_rdev),MINOR(np->i_rdev));
#endif
 return  0 ;           

}

int mechdev_release (struct inode * np , struct file * fp)
{
 
  kfree(mybuff[iminor(np)]);
  printk("release device :major:%d,minor:%d",imajor(np),iminor(np));
    return 0;

}

 ssize_t mychdev_read(struct file *file ,char __user * buff,size_t size, loff_t * off)
{
    *gpedata &= ~(0b11 << 12 );
    copy_to_user(buff,mybuff[iminor(file->private_data)],size);
    printk("usr private get: major:%d,minor:%d,and  read:%d/n",imajor(file->private_data),iminor(file->private_data),size);
    printk("usr dentry get: major:%d,minor:%d,and  read:%d/n",imajor(file->f_path.dentry->d_inode ),iminor(file->f_path.dentry->d_inode),size);
     return size ;
}

 ssize_t mychdev_write(struct file *file,const char __user *buff,size_t size,loff_t *off)
{
    *gpedata |= (0b11 << 12 );
        copy_from_user(mybuff[iminor(file->private_data)],buff,size);   
    printk("my cdev write:%d/n ",size);
    return size ;

}
int __init mycdev_init(void)
{

     size_t i ;
        printk(" mycdev init%s/n",__FUNCTION__);
       if( alloc_chrdev_region(&devid,0,MINOR_NUM,name) )       //分配驱动号(主设备号),次设备号
        {
         printk("alloc cdevid failed /n");
         return ENOMEM;
        }
     ops.read = mychdev_read ;
     ops.write = mychdev_write ;
     ops.open = mychdev_open ;
        //register_chrdev_region();
        cdev_init(&cdev,&ops);  //绑定设备与操作
        cdev_add(&cdev,devid,MINOR_NUM);

        cls = class_create(THIS_MODULE,name);    //创建类
    for(i=0;i<MINOR_NUM;i++)
        device_create(cls,NULL,MKDEV(MAJOR(devid),i),&cdev,"cdev%d",i);
    gpecon = ioremap(GPECON,8);
    gpedata = gpecon+1;
   
    *gpecon &= ~(0b1111<<24) ;
    *gpecon |=  (0b0101<<24) ;
   
    return 0;
}


void __exit mycdev_exit(void)
{
     size_t i ;
    cdev_del(&cdev);
    unregister_chrdev_region(devid,MINOR_NUM);

    for(i=0;i<MINOR_NUM;i++)
        device_destroy(cls,MKDEV(MAJOR(devid),i));
    class_destroy(cls);
   
        printk("hello exit %s/n",__FUNCTION__);
}

module_init(mycdev_init);
module_exit(mycdev_exit);

 

-------------------app------------

main.c

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
 int main()
{
 char * name = "/dev/cdev0";
 char * name1 = "/dev/cdev2";
 int fd ;
 int fd2 ;
 char buff[100] = "wakaka" ;
 char buff2[100] = "hahahah" ;
 char combuff[100];
 char combuff2[100];
 fd = open(name,O_RDWR);
 fd2 = open(name1,O_RDWR);
 
 if((fd < 0) || (fd2 < 0))
    {
    perror("open err:");
    return -1 ;
    }
 int i = 4;
 while( i -- )
    {
     printf("ops debug fd=%d /n",fd);
     write(fd,buff,9);
     write(fd2, buff2,23);   
     sleep(1);
     read(fd , combuff,9 );
     read(fd2 , combuff2,10 );   
     printf("from /dev/cdev0:%s/n",combuff);
     printf("from /dev/cdev2:%s/n",combuff2);
     sleep(1);
    }
}

你可能感兴趣的:(struct,Module,user,File,null,Class)