亚洲一级免费看,特黄特色大片免费观看播放器,777毛片,久久久久国产一区二区三区四区,欧美三级一区二区,国产精品一区二区久久久久,人人澡人人草

操作系統(tǒng)

Linux系統(tǒng)字符設備驅動框架筆記

時間:2025-05-09 13:31:40 操作系統(tǒng) 我要投稿
  • 相關推薦

Linux系統(tǒng)字符設備驅動框架筆記

  不積跬步,何以至千里。掌握知識都是從很小的點開始的。下面是小編整理的Linux系統(tǒng)字符設備驅動框架筆記,歡迎閱讀!

Linux系統(tǒng)字符設備驅動框架筆記

  字符設備是Linux三大設備之一(另外兩種是塊設備,網絡設備),字符設備就是字節(jié)流形式通訊的I/O設備,絕大部分設備都是字符設備,常見的字符設備包括鼠標、鍵盤、顯示器、串口等等,當我們執(zhí)行 ls -l /dev 的時候,就能看到大量的設備文件, c 就是字符設備, b 就是塊設備,網絡設備沒有對應的設備文件。編寫一個外部模塊的字符設備驅動,除了要實現(xiàn)編寫一個模塊所需要的代碼之外,還需要編寫作為一個字符設備的代碼。

  驅動模型

  Linux一切皆文件,那么作為一個設備文件,它的操作方法接口封裝在 struct file_operations ,當我們寫一個驅動的時候,一定要實現(xiàn)相應的接口,這樣才能使這個驅動可用,Linux的內核中大量使用"注冊+回調"機制進行驅動程序的編寫,所謂注冊回調,簡單的理解,就是當我們open一個設備文件的時候,其實是通過VFS找到相應的inode,并執(zhí)行此前創(chuàng)建這個設備文件時注冊在inode中的open函數(shù),其他函數(shù)也是如此,所以,為了讓我們寫的驅動能夠正常的被應用程序操作,首先要做的就是實現(xiàn)相應的方法,然后再創(chuàng)建相應的設備文件。

  #include //for struct cdev

  #include //for struct file

  #include //for copy_to_user

  #include //for error number

  /* 準備操作方法集 */

  /*

  struct file_operations {

  struct module *owner; //THIS_MODULE

  //讀設備

  ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

  //寫設備

  ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

  //映射內核空間到用戶空間

  int (*mmap) (struct file *, struct vm_area_struct *);

  //讀寫設備參數(shù)、讀設備狀態(tài)、控制設備

  long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

  //打開設備

  int (*open) (struct inode *, struct file *);

  //關閉設備

  int (*release) (struct inode *, struct file *);

  //刷新設備

  int (*flush) (struct file *, fl_owner_t id);

  //文件定位

  loff_t (*llseek) (struct file *, loff_t, int);

  //異步通知

  int (*fasync) (int, struct file *, int);

  //POLL機制

  unsigned int (*poll) (struct file *, struct poll_table_struct *);

  。。。

  };

  */

  ssize_t myread(struct file *filep, char __user * user_buf, size_t size, loff_t* offset)

  {

  return 0;

  }

  struct file fops = {

  .owner = THIS_MODULE,

  .read = myread,

  ...

  };

  /* 字符設備對象類型 */

  struct cdev {

  //public

  struct module *owner; //模塊所有者(THIS_MODULE),用于模塊計數(shù)

  const struct file_operations *ops; //操作方法集(分工:打開、關閉、讀/寫、...)

  dev_t dev; //設備號(第一個)

  unsigned int count; //設備數(shù)量

  //private

  ...

  };

  static int __init chrdev_init(void)

  {

  ...

  /* 構造cdev設備對象 */

  struct cdev *cdev_alloc(void);

  /* 初始化cdev設備對象 */

  void cdev_init(struct cdev*, const struct file_opeartions*);

  /* 為字符設備靜態(tài)申請設備號 */

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

  /* 為字符設備動態(tài)申請主設備號 */

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

  MKDEV(ma,mi) //將主設備號和次設備號組合成設備號

  MAJOR(dev) //從dev_t數(shù)據(jù)中得到主設備號

  MINOR(dev) //從dev_t數(shù)據(jù)中得到次設備號

  /* 注冊字符設備對象cdev到內核 */

  int cdev_add(struct cdev* , dev_t, unsigned);

  ...

  }

  static void __exit chrdev_exit(void)

  {

  ...

  /* 從內核注銷cdev設備對象 */

  void cdev_del(struct cdev* );

  /* 從內核注銷cdev設備對象 */

  void cdev_put(stuct cdev *);

  /* 回收設備號 */

  void unregister_chrdev_region(dev_t from, unsigned count);

  ...

  }

  實現(xiàn)read,write

  Linux下各個進程都有自己獨立的進程空間,即使是將內核的數(shù)據(jù)映射到用戶進程,該數(shù)據(jù)的PID也會自動轉變?yōu)樵撚脩暨M程的PID,由于這種機制的存在,我們不能直接將數(shù)據(jù)從內核空間和用戶空間進行拷貝,而需要專門的拷貝數(shù)據(jù)函數(shù)/宏:

  long copy_from_user(void *to, const void __user * from, unsigned long n)

  long copy_to_user(void __user *to, const void *from, unsigned long n)

  這兩個函數(shù)可以將內核空間的數(shù)據(jù)拷貝到回調該函數(shù)的用戶進程的用戶進程空間,有了這兩個函數(shù),內核中的read,write就可以實現(xiàn)內核空間和用戶空間的數(shù)據(jù)拷貝。

  ssize_t myread(struct file *filep, char __user * user_buf, size_t size, loff_t* offset)

  {

  long ret = 0;

  size = size > MAX_KBUF?MAX_KBUF:size;

  if(copy_to_user(user_buf, kbuf,size)

  return -EAGAIN;

  }

  return 0;

  }

【Linux系統(tǒng)字符設備驅動框架筆記】相關文章:

有無操作系統(tǒng)的嵌入式Linux驅動設備有何區(qū)別07-20

Linux系統(tǒng)下USB驅動程序的設計與開發(fā)10-21

Linux系統(tǒng)調用設備的ioctl函數(shù)10-20

Linux系統(tǒng)中怎么掛載外界設備06-14

linux系統(tǒng)命令(經典)01-25

linux系統(tǒng)命令11-23

C語言簡單的字符驅動程序介紹09-22

Linux操作系統(tǒng)學習筆記權限管理09-26

linux系統(tǒng)命令大全08-16