Chinaunix首页 | 论坛 | 博客
  • 博客访问: 45956
  • 博文数量: 21
  • 博客积分: 855
  • 博客等级: 准尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-20 14:19
文章分类
文章存档

2011年(1)

2009年(20)

我的朋友
最近访客

分类: LINUX

2009-04-14 11:27:06

一.   cdev结构体:

struct cdev

{

       Struct kobject kobj;         //内嵌的kobject对象

       Struct module *owner;      //所属模块

       Struct file_operations *ops;   //文件操作结构体

       Struct list_head list;

       Dev_t dev;                //设备号

       Unsigned int count;

}

 

二.   使用下列宏可以从 dev_t获得主设备号和次设备号

MAJOR(dev_t dev)

MINOR(dev_t dev)

 

三.   使用下列宏则可以通过主设备号和设备号生成dev_t

MKDEV(int major, int minor)

 

四.   LINUX2.6内核提供了一组函数用于操作cdev结构体:

Void cdev_init(struct cdev *, struct file_operations *);   //初始化cdev成员

Struct cdev *cdev_alloc(void);         //动态申请一个cdev内存

Void cdev_put(struct cdev *p);        

Int cdev_add(struct cdev *,dev_t, unsigned);  //向系统添加一个cdev

Void cdev_del(struct cdev *);              //向系统删除一个cdev

 

五.   分配和释放设备号

1.       int register_chrdev_region(dev_t from, unsigned count, const char *name);  //申请设备号

2.       void unregister_chrdev_region(dev_t from, unsigned count);       //释放设备号

 

六.   globalmem设备驱动

1.       头文件.宏及设备结构体

#include

#include

#include

#include

#include

#include

#include

#include

 

#define GLOBALMEM_SIZE  0x1000       //全局内存大小

#define MEM_CLEAR       0x1          //清零全局内存

#define GLOBALMEM_MAJOR 254          //预设的globalmem的主设备号

 

static globalmem_major = GLOBALMEM_MAJOR;

 

struct globalmem_dev

{

       struct cdev cdev;

       unsigned char mem[GLOBALMEM_SIZE];

}

 

struct globalmem_dev  dev;       //设备结构体实例

 

 

2.       加载设备驱动:

static void globalmem_setup_cdev()

{

       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_setup_cdev();

       return 0;

}

 

3.       卸载设备驱动:

void globalmem_exit(void)

{

       cdev_del(&dev.cdev);

       unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);

}

 

4.       file_operations结构体:

static const struct file_operations globalmem_fops =

{

       .owner = THIS_MODULE,

       .llseek = globalmem_llseek,

       .read = globalmem_read,

       .write = globalmem_wirte,

       .ioctl = gloalmem_ioctl,

};

 

5.       读函数:

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 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;

             

              prink(KERN_INFO "read %d butes(s) from %d\n", count, p);

       }

      

       return ret;

}

 

6.       写函数:

static ssize_t globalmem_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)

{

       unsigned long p = *ppos;

       int ret =0;

      

              if (p >= GLOBALMEM_SIZE) {

              return count ? -ENXIO : 0;

       }

      

       if (count > GLOBALMEM_SIZE - p) {

              count = GLOBALMEM_SIZE - p;

       }

      

       if (copy_from_user(dev->mem+p, buf, count)) {

              ret = -EFAULT;

       } else {

              *ppos += count;

              ret = count;

             

              prink(KERN_INFO "written %d butes(s) from %d\n", count, p);

       }

      

       return ret;

}

 

7.       seek函数

static loff_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 = file->f_pos;

                 %

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