精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux驅動 | cdev_init、cdev_alloc的區別

系統 Linux
外設有MPU6050、LED兩個設備,他們通過外設電路連接到SOC的對應的引腳上。程序要操作外設,就要通過設置soc中對應的SFR來與外設交互。

[[424054]]

這兩個函數是字符設備初始化相關的內核函數。

要想了解這兩個函數,必須要知道字符設備的架構,以及字符設備創建的流程。

關于字符設備可以參考下面這篇文章 《手把手教Linux驅動3-之字符設備架構詳解,有這篇就夠了》

一、字符設備架構

下面我們以兩個設備:LED、MPU6050為例來講解字符設備的架構

由上圖所示:

1、硬件

外設有MPU6050、LED兩個設備,他們通過外設電路連接到SOC的對應的引腳上。程序要操作外設,就要通過設置soc中對應的SFR來與外設交互。

2、驅動層

  • 每一個字符設備都必須首先定義一個結構體變量struct cdev,并注冊到內核中
  • 所有的該變量在內核中會通過鏈表進程管理,其中成員list用于將所有鏈表串接起來
  • 用于操作外設的功能函數全部被封裝在struct file_operations中,包括read、write等
  • 每一個字符設備都必須要有一個設備號,保存在成員dev中,
  • 主、次設備號只能被分配一次
  • 所有的字符設備號,都由數組chrdevs統一管理
  • chrdevs是一個指針數組,成員類型為**struct char_device_struct ***,下標與字符設備號有一定的對應關系,
  • **struct char_device_struct **中有成員:
  1. unsigned int major; 
  2. struct cdev *cdev;  

major : 是主設備號 cdev : 指向該字符設備號對應的cdev結構體

3、應用層、VFS層

  • 用戶如果想操作硬件,必須調用內核中的struct file_operations中的操作函數,
  • 那么如何才能找到該結構體呢?必須要依賴文件節點來查找,可以通過以下命令來創建
  1. mknod  /dev/led c 250 0 
  2.  mknod 創建設備文件,可以使字符設備,也可以是塊設備 
  3.  /dev/led 設備文件名 
  4.  c  字符設備 
  5.  250  主設備號 
  6.  0    次設備號 

字符設備文件屬性中最重要的屬性就是字符設備號,該設備號和chedevs的下標有一定對應關系

  • 通過mknod創建的文件,VFS層會分配一個結構體變量來維護該文件,類型為struct inode
  • 每新建1個文件內核都會創建不同的結構體變量與之對應
  • 應用程序要操作某個字符設備,那么必須先通過系統調用open()來打開該字符設備
  • 該函數會返回一個唯一的整型文件描述符,同時內核中會分配結構體變量,類型為struct file,并與文件描述符一一對應,該結構體維護在struct task_struct中
  • 每次打開某個文件,都會分配不同的文件描述符,所以需要用不同的變量來保存文件描述符

二、字符設備創建的流程

了解了架構之后,那么我們來看一下內核中完整的創建字符設備的流程及對應的函數調用關系:

如下圖所示,字符設備的創建主要包括以下三個步驟:

  1. 申請設備號
  2. 初始化cdev
  3. 注冊cdev 調用的函數見右側

下面是一個最簡單的額字符設備創建的實例

  1. /*   
  2.  *一口Linux 
  3.  *2021.6.21 
  4.  *version: 1.0.0 
  5. */ 
  6.  
  7. #include <linux/init.h> 
  8. #include <linux/module.h> 
  9. #include <linux/kdev_t.h> 
  10. #include <linux/fs.h> 
  11. #include <linux/cdev.h> 
  12.  
  13. static int major = 237; 
  14. static int minor = 0; 
  15. static dev_t devno; 
  16. static struct cdev cdev; 
  17. static int hello_open (struct inode *inode, struct file *filep) 
  18.  printk("hello_open()\n"); 
  19.  return 0; 
  20. static struct file_operations hello_ops =  
  21.  .open = hello_open, 
  22. }; 
  23. static int hello_init(void) 
  24.  int result; 
  25.  int error;  
  26.  printk("hello_init \n"); 
  27.  devno = MKDEV(major,minor);  
  28.  result = register_chrdev_region(devno, 1, "test"); 
  29.  if(result<0) 
  30.  { 
  31.   printk("register_chrdev_region fail \n"); 
  32.   return result; 
  33.  } 
  34.  cdev_init(&cdev,&hello_ops); 
  35.  error = cdev_add(&cdev,devno,1); 
  36.  if(error < 0) 
  37.  { 
  38.   printk("cdev_add fail \n"); 
  39.   unregister_chrdev_region(devno,1); 
  40.   return error; 
  41.  } 
  42.  return 0; 
  43. static void hello_exit(void) 
  44.  printk("hello_exit \n"); 
  45.  cdev_del(cdev); 
  46.  unregister_chrdev_region(devno,1); 
  47.  return
  48. module_init(hello_init); 
  49. module_exit(hello_exit); 

該實例代碼主要功能:

  1. 申請了字符設備號237
  2. 初始化cdev,并注冊了cdev

應用程序如果要想使用,還必須創建字符設備節點

  1. mknod /dev/test c 237 0 

這樣應用程序就可以通過設備節點/dev/test 調用到對應的內核操作函數.open = hello_open,

  1. /*   
  2.  *一口Linux 
  3.  *2021.6.21 
  4.  *version: 1.0.0 
  5. */ 
  6.  
  7. #include <stdio.h> 
  8. #include <sys/types.h> 
  9. #include <sys/stat.h> 
  10. #include <fcntl.h> 
  11. main() 
  12.  int fd; 
  13.  fd = open("/dev/test",O_RDWR); 
  14.  if(fd<0) 
  15.  { 
  16.   perror("open fail \n"); 
  17.   return
  18.  } 
  19.  printf("open ok \n "); 

三、函數功能和定義

搞懂上面字符設備創建步驟之后,我們就可以來真正分析cdev_init、cdev_alloc這兩個函數了

1. cdev_init()

  1. 原型 
  2. void cdev_init(struct cdev *cdev, const struct file_operations *fops) 
  3.  
  4. 功能 
  5.  用于初始化cdev結構體,并填充其成員ops 
  6. 參數 
  7.    cdev:字符設備 
  8.    fops :驅動操作函數集合 
  9. 返回值 
  10.   無 

該函數實現如下:

  1. /** 
  2.  * cdev_init() - initialize a cdev structure 
  3.  * @cdev: the structure to initialize 
  4.  * @fops: the file_operations for this device 
  5.  * 
  6.  * Initializes @cdev, remembering @fops, making it ready to add to the 
  7.  * system with cdev_add(). 
  8.  */ 
  9. void cdev_init(struct cdev *cdev, const struct file_operations *fops) 
  10.  memset(cdev, 0, sizeof *cdev); 
  11.  INIT_LIST_HEAD(&cdev->list); 
  12.  kobject_init(&cdev->kobj, &ktype_cdev_default); 
  13.  cdev->ops = fops; 

2. cdev_alloc

  1. 原型 
  2. struct cdev *cdev_alloc(void) 
  3.  
  4. 功能 
  5.  用于分配cdev結構體,并添加到內核中 
  6. 參數 
  7. 返回值 
  8.   成功:返回分配的cdev結構體變量指針 
  9.   失敗: 返回NULL 

該函數實現如下:

  1. /** 
  2.  * cdev_alloc() - allocate a cdev structure 
  3.  * 
  4.  * Allocates and returns a cdev structure, or NULL on failure. 
  5.  */ 
  6. struct cdev *cdev_alloc(void) 
  7.  struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); 
  8.  if (p) { 
  9.   INIT_LIST_HEAD(&p->list); 
  10.   kobject_init(&p->kobj, &ktype_cdev_dynamic); 
  11.  } 
  12.  return p; 

注意,該函數分配的cdev需要free掉 該函數沒有初始化cdev->ops成員

四、cdev_alloc()的使用

該函數主要用于讓用戶省去操作cdev的操作,只需要提供**struct file_operations **變量就可以通過以下函數注冊字符設備

  1. static inline int register_chrdev(unsigned int major, const char *name
  2.       const struct file_operations *fops) 
  3.  return __register_chrdev(major, 0, 256, name, fops); 

其中函數__register_chrdev()定義如下:

  1. /** 
  2.  * __register_chrdev() - create and register a cdev occupying a range of minors 
  3.  * @major: major device number or 0 for dynamic allocation 
  4.  * @baseminor: first of the requested range of minor numbers 
  5.  * @count: the number of minor numbers required 
  6.  * @namename of this range of devices 
  7.  * @fops: file operations associated with this devices 
  8.  * 
  9.  * If @major == 0 this functions will dynamically allocate a major and return 
  10.  * its number. 
  11.  * 
  12.  * If @major > 0 this function will attempt to reserve a device with the given 
  13.  * major number and will return zero on success. 
  14.  * 
  15.  * Returns a -ve errno on failure. 
  16.  * 
  17.  * The name of this device has nothing to do with the name of the device in 
  18.  * /dev. It only helps to keep track of the different owners of devices. If 
  19.  * your module name has only one type of devices it's ok to use e.g. the name 
  20.  * of the module here. 
  21.  */ 
  22. int __register_chrdev(unsigned int major, unsigned int baseminor, 
  23.         unsigned int count, const char *name
  24.         const struct file_operations *fops) 
  25.  struct char_device_struct *cd; 
  26.  struct cdev *cdev; 
  27.  int err = -ENOMEM; 
  28.  
  29.  cd = __register_chrdev_region(major, baseminor, countname); 
  30.  if (IS_ERR(cd)) 
  31.   return PTR_ERR(cd); 
  32.  
  33.  cdev = cdev_alloc(); 
  34.  if (!cdev) 
  35.   goto out2; 
  36.  
  37.  cdev->owner = fops->owner; 
  38.  cdev->ops = fops; 
  39.  kobject_set_name(&cdev->kobj, "%s"name); 
  40.  
  41.  err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); 
  42.  if (err) 
  43.   goto out
  44.  
  45.  cd->cdev = cdev; 
  46.  
  47.  return major ? 0 : cd->major; 
  48. out
  49.  kobject_put(&cdev->kobj); 
  50. out2: 
  51.  kfree(__unregister_chrdev_region(cd->major, baseminor, count)); 
  52.  return err; 

可以看到該函數,復用了cdev_alloc()、cdev_add(),我們只需要提供以下3個參數即可:

  1. unsigned int major  主設備號 
  2. const char *name    設備號名字 
  3. const struct file_operations *fops 驅動操作函數集合 

五、結論

cdev_alloc()函數相當于

  1. struct cdev cdev; 
  2. cdev_init($cdev,&hello_ops) 

本文轉載自微信公眾號「一口Linux」

 

責任編輯:姜華 來源: 一口Linux
相關推薦

2013-07-25 13:15:55

iOS開發學習new與allocinit區別

2017-02-14 12:34:28

iOSAllocInit

2021-10-11 08:51:05

Linux console Linux 系統

2011-01-14 17:05:52

Linuxinit

2022-07-07 06:27:59

Python__init____new__

2021-03-11 12:23:13

Linux驅動開發

2012-05-28 15:49:06

Linux凱迪拉克

2010-03-03 09:16:17

2020-12-03 08:59:06

Linux設備驅動

2021-11-29 07:55:45

Linux GPIO Linux 系統

2011-04-11 13:26:25

Linux驅動

2009-12-03 10:12:24

LinuxUnix

2011-09-05 17:44:49

LinuxUnix

2017-11-06 17:16:55

Linux設備驅動并發控制

2021-08-10 11:30:30

Linux代碼中斷控制器

2021-08-03 15:10:26

Linux代碼驅動

2023-05-15 08:58:41

塊設備驅動Linux

2015-07-20 10:00:28

Linux內核編碼風格

2017-03-23 14:30:13

Linux內核驅動編碼風格

2009-12-17 09:56:26

Linux添加驅動模塊
點贊
收藏

51CTO技術棧公眾號

久久精品麻豆| 欧美人体视频xxxxx| 日本伊人精品一区二区三区观看方式| 国产亚洲欧洲高清| av网站在线不卡| 在线观看h网| 91亚洲精品乱码久久久久久蜜桃| 国产精品热视频| www.色小姐com| 香蕉久久夜色精品国产更新时间| 欧美日韩一级片在线观看| 大片在线观看网站免费收看| 久久经典视频| 久久99这里只有精品| 91精品国产高清自在线| 亚洲熟女少妇一区二区| 亚洲精品国产九九九| 日本黄色一区二区| 欧美日韩视频免费| 欧美激情免费| 国产婷婷色一区二区三区在线| 亚洲一区中文字幕| 最近中文字幕免费在线观看| 国产欧美日韩一区二区三区在线| 久久久av亚洲男天堂| 成人片黄网站色大片免费毛片| 精品视频91| 欧美一a一片一级一片| 97视频久久久| 91精品久久| 国产精品国产三级国产普通话99 | 久久久久久久久久久久久国产| 天堂视频中文在线| 丁香桃色午夜亚洲一区二区三区| 国产精品久久久久高潮| 四虎成人在线观看| 国产日本精品| 九色精品美女在线| 成年人一级黄色片| 天天射天天综合网| 日韩中文字幕视频在线观看| 女女互磨互喷水高潮les呻吟| 高潮久久久久久久久久久久久久 | 欧美熟妇交换久久久久久分类 | 在线观看91视频| 亚洲精品乱码久久久久久自慰| 51精品视频| 亚洲国产日韩a在线播放性色| 大桥未久一区二区三区| 成年人网站在线| 中文字幕一区二区三区在线不卡| 日韩中文字幕一区二区| 国产午夜精品一区理论片| 91免费国产在线| 欧美二区在线看| 男男激情在线| 国产欧美一区二区精品忘忧草| 欧美区高清在线| 国产小视频在线| 久久久五月婷婷| 艳女tv在线观看国产一区| 欧美日韩国产精品一区二区三区| 无遮挡的视频在线观看| 欧美国产一区二区| 午夜午夜精品一区二区三区文| 黄色在线小视频| 国产日韩欧美麻豆| 国产婷婷色综合av蜜臀av| 精品久久久噜噜噜噜久久图片| 欧美成人资源| 91成人在线精品| 亚洲欧美自偷自拍另类| 99视频这里有精品| 精品粉嫩aⅴ一区二区三区四区| 欧美熟妇精品一区二区| 精品精品国产毛片在线看| 精品一区精品二区| 蜜桃av免费在线观看| 天天影视天天精品| 欧美精品九九久久| aaa在线视频| 韩国一区二区视频| 99在线观看视频网站| av女名字大全列表| 国产精品女主播av| 男女激情免费视频| 99久久精品一区二区成人| 这里只有精品免费| www.男人天堂| 99精品在线免费在线观看| 欧美贵妇videos办公室| 国产午夜精品久久久久| 激情综合网av| 久久av二区| a视频在线观看免费| 欧美性色19p| 免费不卡av网站| 少妇精品久久久一区二区三区| 久久影视免费观看| 秋霞av一区二区三区| 国产91精品免费| 亚洲免费不卡| 黄色漫画在线免费看| 欧美精品久久一区二区三区| 国产xxxxxxxxx| 91精品秘密在线观看| 日本亚洲欧洲色α| 丁香花免费高清完整在线播放| 国产日韩欧美高清在线| 97超碰国产精品| 日韩成人综合网| 亚洲男人的天堂在线播放| 看片网站在线观看| 久久国产精品一区二区| 免费成人看片网址| 中文字幕电影av| 欧美高清你懂的| 亚洲国产精品网站| 一区二区三区在线播放视频| 在线亚洲观看| 动漫一区二区在线| 黄在线免费观看| 欧美专区日韩专区| 中文字幕一区二区久久人妻网站 | 26uuu另类欧美亚洲曰本| 亚洲欧美日韩国产yyy| 性欧美又大又长又硬| 精品99一区二区| 国产高潮流白浆| 久久av资源网| 亚洲一区二区三区加勒比| 日韩在线影院| 亚洲欧美国产一本综合首页| 国产第100页| 国产精品538一区二区在线| 天天综合中文字幕| 91国内外精品自在线播放| 国产视频精品在线| 国产无人区码熟妇毛片多| 国产在线视频一区二区| 亚洲欧洲一区二区福利| 国产情侣一区二区三区| 中文字幕久热精品视频在线| 无码人妻精品一区二区| 久久久蜜桃精品| 欧美aⅴ在线观看| 亚洲三级精品| 国产成人精品日本亚洲| 久久久久久久影视| 91国偷自产一区二区开放时间 | 成人vr资源| 国产精品一区二区三| 国产鲁鲁视频在线观看免费| 91久久精品一区二区二区| 国产精品揄拍100视频| 久久电影一区| 日韩免费av电影| 欧美日韩卡一| 久久91精品国产| 丰满肉嫩西川结衣av| 午夜精品福利一区二区蜜股av| 熟妇高潮一区二区| 亚洲一区二区三区高清不卡| 蜜桃视频日韩| 成人深夜福利| 久久国产精品久久久久| 成人毛片在线精品国产| 黑人狂躁日本妞一区二区三区 | 欧美色图校园春色| 伊人久久婷婷| 欧洲亚洲一区二区| 久久91视频| 色综合色综合久久综合频道88| 欧美 日韩 国产 在线| 一本色道久久综合亚洲91| 国产又粗又硬视频| 国产黄人亚洲片| 日本精品一区二区三区四区| 日本不卡高清| 99re在线视频观看| 久久毛片亚洲| 久久影院资源网| 午夜一区在线观看| 欧美精品乱码久久久久久按摩| 久久久国产精华液| 久久婷婷国产综合国色天香| 高潮一区二区三区| 日韩视频一区| 伊人狠狠色丁香综合尤物| 国产成人高清精品免费5388| 国产精品91在线观看| 羞羞的视频在线看| 一区二区欧美久久| 成人午夜视频一区二区播放| 欧美少妇bbb| 国产精品第二十页| 国产精品的网站| 变态另类丨国产精品| 极品少妇xxxx精品少妇| 日本精品免费在线观看| 国产精品magnet| 亚洲欧美成人一区| 日韩美女毛片| 亚洲一区二区三区四区视频| 三上悠亚激情av一区二区三区| 久久精品99久久久香蕉| 欧美在线一卡| 精品盗摄一区二区三区| 91免费视频播放| 色偷偷成人一区二区三区91| 久草网视频在线观看| 欧美国产1区2区| 菠萝菠萝蜜网站| 高清视频一区二区| 亚洲三级在线观看视频| 日日噜噜夜夜狠狠视频欧美人| 丁香六月激情网| 伊人成综合网| 日韩精品久久一区二区三区| 国产精品极品国产中出| 91精品国产综合久久久久久丝袜| 日本精品另类| 日韩av不卡电影| 国产h片在线观看| 欧美激情小视频| 伊人手机在线| 欧美成人一区二区三区电影| 在线看免费av| 最近2019好看的中文字幕免费 | 波多野结衣欧美| 亚洲永久在线观看| 国产美女视频一区二区| 成人福利网站在线观看11| 国产成人精品一区二区三区视频 | 中文字幕免费国产精品| 高清毛片在线看| 亚洲图片制服诱惑| 男同在线观看| 国产亚洲欧美日韩美女| 国模精品一区二区| 亚洲网站视频福利| 黄色影院在线播放| 亚洲一区二区国产| 国产特黄在线| 中文字幕亚洲综合久久| 91九色在线porn| 中文字幕亚洲自拍| www在线免费观看视频| 米奇精品一区二区三区在线观看| av在线免费观看网址| 欧美黑人xxxⅹ高潮交| 日韩成人伦理| 国产综合在线视频| 综合日韩av| 国产精品电影一区| 福利一区在线| 91九色视频导航| 视频一区视频二区欧美| 国产精成人品localhost| 日韩精选在线| 亚洲春色在线| 亚洲国产不卡| 中国丰满熟妇xxxx性| 亚洲一级在线| 亚洲成人天堂网| 国产成人一区在线| 亚洲第一黄色网址| 亚洲国产成人在线| 久草视频中文在线| 日韩欧美高清视频| 亚洲网站免费观看| 日韩欧美亚洲一区二区| 天天操天天干天天爽| 亚洲性猛交xxxxwww| 蜜桃视频在线观看www社区 | 国产一卡二卡在线播放| 欧美性xxxx极品高清hd直播| 中文字幕一区二区人妻| 日韩欧美国产精品一区| 久久视频www| 欧美另类交人妖| 国产超碰精品| 96sao精品视频在线观看| 天堂在线精品| 中文字幕剧情在线观看一区| 狠狠综合久久av一区二区老牛| 无码aⅴ精品一区二区三区浪潮 | 下面一进一出好爽视频| 99精品欧美一区| 国内毛片毛片毛片毛片毛片| 亚洲制服欧美中文字幕中文字幕| 91在线视频在线观看| 欧美一区二区视频免费观看| 亚洲人视频在线观看| 日韩在线精品视频| 天堂8中文在线最新版在线| 91精品国产综合久久男男| 卡通动漫精品一区二区三区| 亚洲三区在线| 亚洲综合好骚| 麻豆av免费看| 一区在线中文字幕| 国产又黄又猛又粗又爽| 日韩视频中午一区| aaa日本高清在线播放免费观看| 国外色69视频在线观看| 99热这里有精品| 色女人综合av| 亚洲影视综合| 艳妇乳肉豪妇荡乳xxx| 中文字幕在线一区免费| 无码一区二区三区在线观看| 精品欧美一区二区三区精品久久 | 57pao国产精品一区| 亚洲精品一区二区三区中文字幕 | 国内自拍一区| 网站在线你懂的| 中文字幕成人网| 久久青青草原亚洲av无码麻豆 | 亚洲va电影大全| 日韩激情免费| 婷婷丁香激情网| 久久久精品tv| 亚洲黄网在线观看| 亚洲另类xxxx| 在线能看的av网址| 国产欧美日韩一区二区三区| 午夜精品久久99蜜桃的功能介绍| www.久久av.com| 国产精品伦理一区二区| 中国a一片一级一片| 亚洲精品之草原avav久久| 国产调教在线| 国产一区二区精品免费| 欧美全黄视频| 91传媒理伦片在线观看| 亚洲激情成人在线| 精品国产一级片| 欧美第一页在线| 成人av婷婷| 黄色国产一级视频| eeuss国产一区二区三区 | 国产日韩欧美一区二区三区在线观看| 少妇极品熟妇人妻无码| 一二三区精品视频| 亚洲av无码国产精品永久一区| 欧美精品在线观看91| 亚洲精品a区| 少妇人妻大乳在线视频| av午夜一区麻豆| 亚洲免费在线视频观看| 亚洲日韩第一页| 久久婷婷五月综合色丁香| 亚洲激情一区二区| 国产一区二区调教| www.av视频| 亚洲国产精品久久久久秋霞不卡| 2021中文字幕在线| 欧美日韩一区二| 久久国产剧场电影| 精品国产欧美日韩不卡在线观看| 欧美v日韩v国产v| 免费高潮视频95在线观看网站| 欧美极品色图| 久久精品国产亚洲高清剧情介绍 | 国产美女免费网站| 欧美日韩高清一区二区不卡 | 久久6免费高清热精品| 人妻av无码一区二区三区| 日韩高清二区| 国产精品视频专区| 成人在线观看免费播放| 性金发美女69hd大尺寸| 九九热精品视频在线观看| 人妻丰满熟妇av无码区app| 国产精品久久看| 亚洲成人黄色片| 国产91在线视频| 欧美成人国产| 天天躁日日躁aaaxxⅹ| 欧美老女人在线| 高清精品在线| 亚洲天堂电影网| 99久久伊人精品| 在线免费观看一级片| 欧美激情免费视频| 精品99在线| www.美色吧.com| 欧美亚洲日本一区| 动漫一区二区| 亚洲国产精品日韩| av在线不卡观看免费观看| 超碰在线97观看| 久久久久久这里只有精品| 色综合天天爱| 中文在线一区二区三区| 欧美一区二区成人6969| 精品123区| 男人日女人逼逼| 樱花影视一区二区|