Chinaunix首页 | 论坛 | 博客
  • 博客访问: 149251
  • 博文数量: 52
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 316
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-19 22:20
文章分类
文章存档

2016年(43)

2015年(9)

我的朋友

分类: 其他平台

2016-05-07 17:37:39

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


#define GLOBALMEM_SIZE 0x1000 //全局内存大小
#define MEM_CLEAR 0x1  //清全局内存
#define GLOBALMEM_MAJOR 250  //预设主设备号

static int globalmem_major = GLOBALMEM_MAJOR;
struct globalmen_dev{
struct cdev cdev;
unsigned char mem[GLOBALMEM_SIZE];//全局内存
};
struct globalmen_dev dev;


static ssize_t globalmem_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
{
        unsigned long p = *ppos;
        int ret = 0;
        if(p >= GLOBALMEM_SIZE)
        {
            return 0;
        }
        if(count > GLOBALMEM_SIZE -p)
        {
            count = GLOBALMEM_SIZE -p;
        }
        //copy_to_user 数据从内存 空间拷贝到用户空间
        if(copy_to_user(buf,(void*)(dev.mem+p),count))
        {
        ret = -EFAULT;
        }
        else
        {
            *ppos += count;
            ret = count;
            pintk(KERN_INFO "read %ld bytes(s) from %ld\n",(unsigned long)count,p);
        }
        return ret;
}




static ssize_t globalmem_write(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
{
        unsigned long p = *ppos;
        int ret = 0;
        if(p >= GLOBALMEM_SIZE)
        {
            return 0;
        }
        f(count > GLOBALMEM_SIZE - p)
        {
            count = GLOBALMEM_SIZE - p;
        }
        //copy_from_user  数据从用户空间拷贝到内核空间
        if(copy_from_user(dev.mem+p,buf,count))
        {
            ret = -EFAULT;
        }
        else
        {
            *ppos += count;
            ret = count;
            printk(KERN_INFO "write %ld bytes(s) from %ld\n",(unsigned long)count,p);
        }
        return ret;
}
static ssize_t globalmem_llseek(struct file *filp,loff_t offset,int orig)
{
        loff_t ret;
        switch(orig)
        {
            case 0:
            if(offset < 0)
            {
                ret = -EINVAL;
                break;
            }
            if((unsigned int)offset > GLOBALMEM_SIZE)
        {
            ret = -EINVAL;
            break;
        }
         filp->f_pos = (unsigned int)offset;
        ret  = filp->f_pos;
        break;
       case 1:
            if((filp->f_pos+offset) > GLOBALMEM_SIZE)
            {
                ret = -EINVAL;
                break;
            }
            filp->f_pos += offset;
            ret = filp->f_pos;
        break;
    default:
            ret  = -EINVAL;
    }
    return ret; 
}
static int globalmem_ioctl(struct inode *inodep,struct file *filp,unsigned int cmd,unsigned long arg)
{
        switch(cmd)
        {
                case MEM_CLEAR:
                    memset(dev.mem,0,GLOBALMEM_SIZE);
                    printk(KERN_INFO"globalmem is set to zero\n");
                    break;
            default:
                return -EINVAL;
        }
        return 0;
}








static const struct file_operations globalmem_fops = 
{
    . owner    = THIS_MODULE,
    .llseek   = globalmem_llseek,
    .read     = globalmem_read,
    .write    = globalmem_write,
    .ioctl = globalmem_ioctl,
};


static void globalmem_setup_cdev()
{
    int err,devno = MKDEV(globalmem_major,0);
    cdev_init(&dev,&globalmem_fops);
    dev.cdev.owner = THIS_MODULE;
    err = cdev_add(&dev.cdev,devno,1);
    if(err)
    {
        printk(KERN_NOTICE"Error %d adding golmem",err);
    }
}
//globalmem驱动加载函数
int globalmem_init(void)
{
    int result;
    dev_t devno = MKDEV(globalmem_major,0);
    //申请字符设备驱动区域
    if(globalmem_major)
    {
        result = register_chrdev_region(devno,1,"globalmem");
    }
    else
    {
        / /动态申请主设备号
           result = alloc_chrdev_region(&devno,0,1,"globalmem");
            globalmem_major = MAJOR(devno);
    }
    if(result < 0)
    {
        return result;
    }
    globalmem_setup_cdev();
    return 0;
}
//设备驱动卸载函数
void globalmem_exit()
{
    cdev_del(&dev.cdev);
    unregister_chrdev_region(MKDEV(globalmem_major,0),1);
}
module_init(globalmem_init);
module_exit(globalmem_exit);
MODULE_AUTHOR("chengyouliang2016/5/7");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("a test memuse");
MODULE_ALIAS("a simplest module");


//用户空间测试
# cat /proc/devices 
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
 10 misc
 13 input
 14 sound
 29 fb
 90 mtd
 99 ppdev
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
204 s3c2410_serial
250 globalmem
253 usb_endpoint
254 rtc


Block devices:
  1 ramdisk
  7 loop
  8 sd
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
 
# mknod /dev/globalmem c 250 0
# echo "hello world" > /dev/globalmem 
# cat /dev/globalmem 
read 4096 bytes(s) from 0
hello world































































































阅读(1761) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~