字符設備驅動學習

字符設備驅動的學習

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()等函數是驅動設計的主體工作。

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