国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux 字符設備驅動框架詳細介紹

2019-11-02 16:41:02
字體:
來源:轉載
供稿:網友

Linux 字符設備驅動框架

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

驅動模型

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

#include <linux/cdev.h> //for struct cdev#include <linux/fs.h>  //for struct file#include <asm-generic/uaccess.h>  //for copy_to_user#include <linux/errno.h>      //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 *);  //讀寫設備參數、讀設備狀態、控制設備  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),用于模塊計數  const struct file_operations *ops; //操作方法集(分工:打開、關閉、讀/寫、...)  dev_t dev;             //設備號(第一個)  unsigned int count;         //設備數量  //private  ...};static int __init chrdev_init(void){  ...  /* 構造cdev設備對象 */  struct cdev *cdev_alloc(void);  /* 初始化cdev設備對象 */  void cdev_init(struct cdev*, const struct file_opeartions*);  /* 為字符設備靜態申請設備號 */  int register_chedev_region(dev_t from, unsigned count, const char* name);  /* 為字符設備動態申請主設備號 */  int alloc_chedev_region(dev_t* dev, unsigned baseminor, unsigned count, const char* name);  MKDEV(ma,mi)  //將主設備號和次設備號組合成設備號  MAJOR(dev)   //從dev_t數據中得到主設備號  MINOR(dev)   //從dev_t數據中得到次設備號  /* 注冊字符設備對象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);  ...}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 周宁县| 黎平县| 灌云县| 隆林| 措勤县| 庄浪县| 灵武市| 桂东县| 江津市| 苏尼特右旗| 汕尾市| 始兴县| 鄄城县| 桦南县| 玉屏| 鹰潭市| 兴山县| 遵化市| 龙胜| 奉化市| 南宁市| 昭苏县| 阿拉善左旗| 沧州市| 福清市| 姚安县| 阜城县| 惠水县| 东乡县| 高青县| 阳原县| 泸定县| 纳雍县| 佛学| 德兴市| 临西县| 乐陵市| 鄂温| 平邑县| 木兰县| 咸阳市|