免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1599 | 回复: 1
打印 上一主题 下一主题

一个错误百出的 符号设备驱动 高手能否看下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-15 23:05 |只看该作者 |倒序浏览
[code]
#include <linux/module.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/segment.h>
#include<linux/errno.h>
#include<linux/io.h>
#include<linux/cdev.h>
#include<linux/init.h>
#include<linux/mm.h>
#include<linux/asm.h>
#include<linux/sched.h>
#include<linux/system.h>
#include<linux/uaccess.h>
MODULE_LICENSE("Dual BSD/GPL");
#define GLOBALMEM_SIZE 0x1000 //内存  4kb
#define MEM_CLEAR  0x1  //清零内存
#define GLOBALMEM_MAJOR 254 //预设主设备号
static  int globalmem_major=GLOBALMEM_MAJOR;
struct globalmem_dev
{
    struct cdev cdev;
    unsigned char mem[GLOBALMEM_MAJOR];
}
struct globalmem_dev *globalmem_devp;
int globalmem_open(struct inode *inode,struct file* flip)
{
     filp->private_data=globalmem_devp;
     return 0;
}
int global_release(struct inode* inode,struct file *flip)
{
     return 0;
}

static int globalmem_ioctl(struct inode *inodep,struct file *flip,unsigned int cmd ,unsigned long arg)
{
     struct globalmem_dev *dev=flip->private_data;
     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 ssize_t globalmem_read(struct file *flip,char __user *buf,size_t size,loff_t *ppos)
{
    unsigned long p=*ppos ;
    unsigned int count=size;
    int ret =0;
    struct globalmem_dev *dev =filp->private_data;

    if(p>=GLOBALMEM_SIZE)
               {
       return count? -ENXIO:0;
                }
    if(count>GLOBALMEM_SIZE-p)
                 {
          count=GLOBALMEM_SIZE-p;
                  }
    if(copy_to_user(buf,(void*)(dev->mem+p),count))
               {
           ret=-EFAULT;
               }
    else
               {
        *ppos+=count;
         ret=count;
         printk(KERN_INFO "rea %d bytes(s) from %d \n",count,p);
                 }
     return  ret;
}
static ssize_t globalmem_write(struct file *flip,const char __user *buf,size_t size,loff_t *ppos)
{
    unsigned long p=*ppos;
    unsigned int count=size;
    int ret =0;
    struct globalmem_dev * dev=flip->private_data;
    if(p>=GLOBALMEM_SIZE)return count? -ENXIO:0;
    if(count>GLOBAL_SIZE-p)count=GLOBALMEM_SIZE-p;
    if(copy_from_user(dev->mem+p,buf,count))ret=-EFAULT;
    else
           {
       *ppos+=count;
        ret=count;
        printk(KEN_INFO "write %d bytes(s) from %d \n",count,p);
            }
    return ret;
}
//seek 函数。
static loff_t globalmem_llseek(struc file *flip,loff_t offset,int orig)
{
     loff_t ret=0;
     switch(orig)
                  {
        case 0:
          if(offset<0)
                                {
               ret=- EINVAL;
               break;
                                 }
          if((unsigned int)offset>GLOBALMEM_SIZE)
                                {
               ret=-EINVAL;
               break;
                                  }  
          flip->f_pos =(unsigned int)offset;
          ret=flip->f_pos;
          break;
       case 1:
           if((flip->f_pos+offset)>GLOBALMEM_SIZE)
                                  {
               ret=-EINVAL;
               break;
                                   }
           if((flip->f_pos+offset)<0)
                                   {
               ret=-EINVAL;
               break;
                                   }
           flip->f_pos+=offset;
           ret=flip->f_pos;
           break;
        default:
           ret=-EINVAL;
                   }
     return ret;
}
//ioctl()函数 用于清零
static int globalmem_ioctl(struct inode* inodep,struct file *flip,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,
    .open=globalmem_open,
    .release=globalmem_release,
};
static void globalmem_setup_cdev(struct globalmem_dev *dev,int index)
{
     int err,devno=MKDEV(globalmem_major,0);
     cdev_init(&dev.cdev,&globalmem_fops);
     dev.cdev.owner=THIS_MODULE;
     dev.cdev.ops=&globalmem_fops;
     err=cdev_add(&dev.cdev,devno,1);
     if(err)printk(KERN_NOTICE"ERROR %d adding globalmem",err);
}
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_devp=kmalloc(sizeof(struct globalmem_dev),GFP_KERNEL);
    if(!globalmem_devp)
               {
        result=-ENOMEM;
        goto fail_malloc;
               }
    memset(globalmem_devp,0,sizeof(struct globalmem_dev));
    globalmem_setup_cdev(globalmem_devp,0);  //注册初始化cdev,
    return 0;
    fail_malloc:unregister_cdev(globalmem_devp,0);
    return 0;
}
void globalmem_exit(void)
{
      cdev_del(&dev.cdev);//注销cdev
      kfree(globalmem_devp);//释放内存
      unregister_chrdev_region(MKDEV(globalmem_major,0),1);//注销设备号
}
[/code]

论坛徽章:
1
天蝎座
日期:2013-10-23 21:11:03
2 [报告]
发表于 2009-11-16 12:40 |只看该作者
把错误信息贴出来吧

PS:你用了[code][/code]为什么没有效果?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP