亚洲国产日韩欧美在线a乱码,国产精品路线1路线2路线,亚洲视频一区,精品国产自,www狠狠,国产情侣激情在线视频免费看,亚洲成年网站在线观看

Linux系統(tǒng)字符設(shè)備驅(qū)動(dòng)框架筆記

時(shí)間:2025-11-04 04:35:35 操作系統(tǒng) 我要投稿

Linux系統(tǒng)字符設(shè)備驅(qū)動(dòng)框架筆記

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

Linux系統(tǒng)字符設(shè)備驅(qū)動(dòng)框架筆記

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

  驅(qū)動(dòng)模型

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

  #include /pic/p>

  #include /pic/p>

  #include /pic/p>

  #include /pic/p>

  /* 準(zhǔn)備操作方法集 */

  /*

  struct file_operations {

  struct module *owner; /pic/p>

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

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

  /pic/p>

  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,

  ...

  };

  /* 字符設(shè)備對(duì)象類(lèi)型 */

  struct cdev {

  /pic/p>

  struct module *owner; /pic/p>

  const struct file_operations *ops; /pic/寫(xiě)、...)

  dev_t dev; /pic/p>

  unsigned int count; /pic/p>

  /pic/p>

  ...

  };

  static int __init chrdev_init(void)

  {

  ...

  /* 構(gòu)造cdev設(shè)備對(duì)象 */

  struct cdev *cdev_alloc(void);

  /* 初始化cdev設(shè)備對(duì)象 */

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

  /* 為字符設(shè)備靜態(tài)申請(qǐng)?jiān)O(shè)備號(hào) */

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

  /* 為字符設(shè)備動(dòng)態(tài)申請(qǐng)主設(shè)備號(hào) */

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

  MKDEV(ma,mi) /pic/p>

  MAJOR(dev) /pic/p>

  MINOR(dev) /pic/p>

  /* 注冊(cè)字符設(shè)備對(duì)象cdev到內(nèi)核 */

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

  ...

  }

  static void __exit chrdev_exit(void)

  {

  ...

  /* 從內(nèi)核注銷(xiāo)cdev設(shè)備對(duì)象 */

  void cdev_del(struct cdev* );

  /* 從內(nèi)核注銷(xiāo)cdev設(shè)備對(duì)象 */

  void cdev_put(stuct cdev *);

  /* 回收設(shè)備號(hào) */

  void unregister_chrdev_region(dev_t from, unsigned count);

  ...

  }

  實(shí)現(xiàn)read,write

  Linux下各個(gè)進(jìn)程都有自己獨(dú)立的進(jìn)程空間,即使是將內(nèi)核的數(shù)據(jù)映射到用戶(hù)進(jìn)程,該數(shù)據(jù)的PID也會(huì)自動(dòng)轉(zhuǎn)變?yōu)樵撚脩?hù)進(jìn)程的PID,由于這種機(jī)制的存在,我們不能直接將數(shù)據(jù)從內(nèi)核空間和用戶(hù)空間進(jìn)行拷貝,而需要專(zhuān)門(mén)的拷貝數(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)

  這兩個(gè)函數(shù)可以將內(nèi)核空間的數(shù)據(jù)拷貝到回調(diào)該函數(shù)的用戶(hù)進(jìn)程的用戶(hù)進(jìn)程空間,有了這兩個(gè)函數(shù),內(nèi)核中的read,write就可以實(shí)現(xiàn)內(nèi)核空間和用戶(hù)空間的數(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)字符設(shè)備驅(qū)動(dòng)框架筆記】相關(guān)文章:

有無(wú)操作系統(tǒng)的嵌入式Linux驅(qū)動(dòng)設(shè)備有何區(qū)別11-24

Linux系統(tǒng)調(diào)用設(shè)備的ioctl函數(shù)03-01

Linux系統(tǒng)下USB驅(qū)動(dòng)程序的設(shè)計(jì)與開(kāi)發(fā)01-19

Linux系統(tǒng)中怎么掛載外界設(shè)備10-04

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

linux系統(tǒng)命令(經(jīng)典)10-31

Linux操作系統(tǒng)學(xué)習(xí)筆記權(quán)限管理08-20

C語(yǔ)言簡(jiǎn)單的字符驅(qū)動(dòng)程序介紹03-10

Linux系統(tǒng)的網(wǎng)速操作02-24

  • 相關(guān)推薦