Chinaunix首页 | 论坛 | 博客
  • 博客访问: 722594
  • 博文数量: 105
  • 博客积分: 3532
  • 博客等级: 中校
  • 技术积分: 1328
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-20 18:57
文章分类

全部博文(105)

文章存档

2015年(1)

2014年(1)

2013年(7)

2012年(14)

2011年(21)

2010年(61)

分类: 嵌入式

2010-08-21 07:08:27

这只是一个模板,并没有实现什么功能,需要的功能可以在此基础上添加

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/security.h>

#define MRY_MAJOR 100

#define uint unsigned int
#define ulong unsigned long

static int mry_major=MRY_MAJOR;

typedef struct
{
    struct cdev dev;
    //add private data

}mry_dev;

mry_dev *_pdev;

int mry_open(struct inode *pinode,struct file *pfile)
{
    pfile->private_data=_pdev;
    return 0;
}

int mry_release(struct inode *pinode,struct file *pfile)
{
    return 0;
}

static int mry_ioctl(struct inode *pinode,struct file *pfile,uint cmd,ulong arg)
{
    mry_dev *pdev=pfile->private_data;
    switch(cmd)
    {
        case 1:break;
        default:
            return -EINVAL;
    }
    return 0;
}

static int mry_read(struct file *pfile,char __user *buf,size_t size,loff_t *ppos)
{
    ulong p=*ppos;
    uint count=size;
    int rs=0;
    mry_dev *pdev=pfile->private_data;
#if 0
    if(copy_to_user(buf,(void*)(pdev->mem+p),count)
    {
        rs=-EFAULT;
    }
    else
    {
        *ppos+=count;
        rs=count;
        printk(KERN_INFO "read %d bytes from %d\n",count,p);
    }
#endif
    return rs;
}

static int mry_write(struct file *pfile,const char __user *buf,size_t size,loff_t *ppos)
{
    ulong p=*ppos;
    uint count=size;
    int rs=0;
    mry_dev *pdev=pfile->private_data;
#if 0
    if(copy_from_user(pdev->mem+p,buf,count)
    {
        rs=-EFAULT;
    }
    else
    {
        *ppos+=count;
        rs=count;
        printk(KERN_INFO "write %d bytes from %d\n",count,p);
    }
#endif
    return rs;
}

static const struct file_operations _fops=
{
.owner=THIS_MODULE,
.read=mry_read,
.write=mry_write,
.ioctl=mry_ioctl,
.open=mry_open,
.release=mry_release,
};

static void mry_setup_cdev(mry_dev *pdev,int index)
{
    int err,devno=MKDEV(mry_major,index);
    cdev_init(&pdev->dev,&_fops);
    pdev->dev.owner=THIS_MODULE;
    pdev->dev.ops=&_fops;
    err=cdev_add(&pdev->dev,devno,1);
    if(err)
        printk(KERN_NOTICE "Error %d adding LED %d",err,index);
}

int mry_init(void)
{
    int rs;
    dev_t devno=MKDEV(mry_major,0);
    
    if(mry_major)
        rs=register_chrdev_region(devno,1,"mrydriver");
    else
    {
        rs=alloc_chrdev_region(&devno,0,1,"mrydriver");
        mry_major=MAJOR(devno);
    }
    
    if(rs<0){
        return rs;
    }
    _pdev=kmalloc(sizeof(mry_dev),GFP_KERNEL);
    
    if(!_pdev)
    {
        rs=-ENOMEM;
        goto fail_malloc;
    }
    memset(_pdev,0,sizeof(mry_dev));
    mry_setup_cdev(_pdev,0);
    printk(KERN_INFO "mry driver ok");
    return 0;
fail_malloc:
    printk(KERN_INFO "failed");
    unregister_chrdev_region(devno,1);
    return rs;
}

void mry_exit(void)
{
    cdev_del(&_pdev->dev);
    kfree(_pdev);
    unregister_chrdev_region(MKDEV(mry_major,0),1);
}

MODULE_AUTHOR("MrY");
MODULE_LICENSE("Dual BSD/GPL");
module_param(mry_major,int,S_IRUGO);
module_init(mry_init);
module_exit(mry_exit);


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

上一篇:Hello驱动

下一篇:LED定时闪烁的driver

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