字符设备驱动学习

字符设备驱动的学习

1.首先介绍几个重要的结构体:

1.1  cdev结构体描述字符设备

Struct  cdev

{

  struct kobject kobj; /*内嵌的kobject对象*/

  

   sruct module *owner;  /*所属模块*/

   

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

 

  Struct list_head list;

  

  dev_t  dev ;           //设备号

   unsigned int count;

   

}

其中file_operations定义了字符设备驱动提供给虚拟文件系统的接口函数,void cdev_init(struct cdev*, struct file_operations *);这个函数用于初始化cdev的成员,并且建立cdevfile_operations之间的链接。

void cdev_init(struct cdev *cdev,struct file_operations *fops)

{

   memset(cdev, 0 , sizeof  *cdev);

   

    INIT_LIST_HEAD(&cdev->list);

 

    cdev->kobj.ktype = &ktype_cdev_default;

 

    kobject_init(&cdev->kobj);

   

    cdev->ops = fops;         //讲传入的文件操作结构体指针赋值给cdevops*

 

}

 

cdev_add()函数和cdev_del()函数用于向操作系统添加和删除一个cdev,完成字符设备的注册与注销。

    

 

 

注册字符设备之前,首先调用register_chardev_region()或者alloc_chrdev_region函数向系统申请设备号,这两个函数的原型如下:

int register_chardev_region(dev_t from ,unsigned int count ,const char *name);

int alloc_chrdev_region(dev_t *dev, unsigned int baseminor ,unsigned int count ,const char *name);

其中第二个函数用于向设备动态申请未被占用的设备号。

 

 

字符设备驱动的组成

2.1.定义一个xxx_dev_t结构体可以包含设备所涉及的cdev,私有数据以及信号量等信息。常见的设备结构体、模块加载和卸载函数形式如下所示

 struct   xxx_dev_t

 

{

   struct cdev  cdev

   

  、、、、、

  } XXX_dev;

  

  

  //获取字符设备号

  static int __init xxx_init(void)

  {

  ....

  cdev_init(&xxx_dev.cdev,  &xxx_fops)

  xxx_dev.cdev.owner = THIS_MODULE;

  

  if(xxx_major)

  {

    register_chrdev_region(xxx_dev_no, 1 , DEV_NAME);

    

    

  }

  else

  {

  alloc_chrdev_region(&xxx_dev_no, 0, 1, DEV_NAME);

  }

  

  ret = cdev_add(&xxx_dev.cdev , xxx_dev_no, 1);  //注册设备

  .。。。。。

  }

   

 

 

   //设备驱动模块卸载函数

  static void __exit xxx_exit(void )

  {

 

  unregister_chrdev_region(xxx_dev_ni, 1);//释放占用的设备号

  cdev_del(&xxx_dev.cdev);           //注销设备

  

  

  }

  

2.2.file_operations结构体中的成员函数最常见的3个函数如下所示。

      ssize_t xxx_read(struct file *filp, char __user *buf, size_t count,  loff_t *f_pos )

{

  .。。。

copy_to_user(buf , ... ,  ....);

。。。

}

 

//写设备

ssize_t xxx_write(struct file *filp, const char __user *buf, size_t count,  loff_t *f_pos)

{

。。。

copy_from_user(。。。, buf ,  。。。)

 

}

 

int xxx_ioctl(stuect inode *inode ,struct file *filp ,unsigned int cmd ,unsigned int long arg)

{

.....

 

switch(cmd)

{

case XXX_CMD1:

.....

break;

 

case XXX_CMD2:

.....

break;

default:

 

return -ENOTTY;

}

return 0;

}

 

 

字符设备室3大类设备(字符设备、块设备和网络设备)中较简单的一类设备,其驱动程序中完成的主要工作是初始化、添加和删除cdev结构体,申请和释放设备号,以及填充file_operations结构体中的操作函数,实现file_operations结构体重的read()write()ioctl()等函数是驱动设计的主体工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章