娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

Smart210學習記錄-------Linux設備驅動結構

發布者:mu22最新更新時間:2025-01-22 來源: cnblogs關鍵字:Smart210  Linux 手機看文章 掃描二維碼
隨時隨地手機看文章

cdev結構體

 

1 struct cdev {
2 struct kobject kobj; /* 內嵌的 kobject 對象 */
3 struct module *owner; /*所屬模塊*/
4 struct file_operations *ops; /*文件操作結構體*/
5 struct list_head list;

6    dev_t dev;           /*設備號*/

7 unsigned int count; 
8 }; 


1.struct file_operations {

2 struct module *owner;

3 /* 擁有該結構的模塊的指針,一般為 THIS_MODULES */

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

5 /* 用來修改文件當前的讀寫位置 */

6 ssize_t(*read)(struct file *, char _ _user *, size_t, loff_t*);

7 /* 從設備中同步讀取數據 */

8 ssize_t(*write)(struct file *, const char _ _user *, size_t, loff_t*);

9 /* 向設備發送數據*/

10 ssize_t(*aio_read)(struct kiocb *, char _ _user *, size_t, loff_t);

11 /* 初始化一個異步的讀取操作*/

12 ssize_t(*aio_write)(struct kiocb *, const char _ _user *, size_t, loff_t);

13 /* 初始化一個異步的寫入操作*/

14 int(*readdir)(struct file *, void *, filldir_t);

15 /* 僅用于讀取目錄,對于設備文件,該字段為 NULL */

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

17 /* 輪詢函數,判斷目前是否可以進行非阻塞的讀取或寫入*/

18 int(*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);

19 /* 執行設備 I/O 控制命令*/

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

21 /* 不使用 BLK 的文件系統,將使用此種函數指針代替 ioctl */

22 long(*compat_ioctl)(struct file *, unsigned int, unsigned long);

23 /* 在 64 位系統上,32 位的 ioctl 調用,將使用此函數指針代替*/

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

25 /* 用于請求將設備內存映射到進程地址空間*/

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

27 /* 打開 */

28 int(*flush)(struct file*);

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

30 /* 關閉*/

31 int (*fsync) (struct file *, struct dentry *, int datasync);

32 /* 刷新待處理的數據*/

33 int(*aio_fsync)(struct kiocb *, int datasync);

34 /* 異步 fsync */

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

36 /* 通知設備 FASYNC 標志發生變化*/

37 int(*lock)(struct file *, int, struct file_lock*);

38 ssize_t(*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);

39 /* 通常為 NULL */

40 unsigned long(*get_unmapped_area)(struct file *,unsigned long, unsigned long,

41 unsigned long, unsigned long);

42 /* 在當前進程地址空間找到一個未映射的內存段 */

43 int(*check_flags)(int);

44 /* 允許模塊檢查傳遞給 fcntl(F_SETEL...)調用的標志 */

45 int(*dir_notify)(struct file *filp, unsigned long arg);

46 /* 對文件系統有效,驅動程序不必實現*/

47 int(*flock)(struct file *, int, struct file_lock*);

48 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t,

49 unsigned int); /* 由 VFS 調用,將管道數據粘接到文件 */

50 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t,

51 unsigned int); /* 由 VFS 調用,將文件數據粘接到管道 */

52 int (*setlease)(struct file *, long, struct file_lock **);

53 };


Linux 2.6 內核提供了一組函數用于操作 cdev 結構體:

void cdev_init(struct cdev *, struct file_operations *); 用于初始化 cdev 的成員,并建立 cdev 和 file_operations 之間的連接

struct cdev *cdev_alloc(void); cdev_alloc()函數用于動態申請一個 cdev 內存

void cdev_put(struct cdev *p);

int cdev_add(struct cdev *, dev_t, unsigned); cdev_add()函數和 cdev_del()函數分別向系統添加和刪除一個 cdev,完成字符設備的注冊和注

銷。對 cdev_add()的調用通常發生在字符設備驅動模塊加載函數中,而對 cdev_del()函數的調用則

通常發生在字符設備驅動模塊卸載函數中。

void cdev_del(struct cdev *);


cdev 結構體的 dev_t 成員定義了設備號,為 32 位,其中 12 位主設備號,20 位次設備號。使

用下列宏可以從 dev_t 獲得主設備號和次設備號:

MAJOR(dev_t dev)

MINOR(dev_t dev)

而使用下列宏則可以通過主設備號和次設備號生成 dev_t:

MKDEV(int major, int minor)


分配和釋放設備號

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

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


void unregister_chrdev_region(dev_t from, unsigned count);


Linux字符設備的組成


1  /* 設備結構體 

2  struct xxx_dev_t { 

3      struct cdev cdev; 

4    ... 

5  } xxx_dev; 

6  /* 設備驅動模塊加載函數 

7  static int _ _init xxx_init(void) 

8  { 

9    ... 

10   cdev_init(&xxx_dev.cdev, &xxx_fops); /* 初始化 cdev */ 

11   xxx_dev.cdev.owner = THIS_MODULE; 

12   /* 獲取字符設備號*/ 

13   if (xxx_major) { 

14       register_chrdev_region(xxx_dev_no, 1, DEV_NAME); 

15   } else { 

16       alloc_chrdev_region(&xxx_dev_no, 0, 1, DEV_NAME); 

17   } 

18    

19   ret = cdev_add(&xxx_dev.cdev, xxx_dev_no, 1); /* 注冊設備*/ 

20   ... 

21 } 

22 /*設備驅動模塊卸載函數*/ 

23 static void _ _exit xxx_exit(void) 

24 { 

25    unregister_chrdev_region(xxx_dev_no, 1); /* 釋放占用的設備號*/ 

26    cdev_del(&xxx_dev.cdev); /* 注銷設備*/ 

27   ... 

28 } 

29 module_init(xxx_init);

30 module_exit(xxx_exit);


字符設備驅動的 file_operations 結構體中成員函數


1   /* 讀設備*/ 

2   ssize_t xxx_read(struct file *filp, char __user *buf, size_t count, 

3       loff_t*f_pos) 

4   { 

5       ... 

6       copy_to_user(buf, ..., ...); 

7       ... 

8   } 

9   /* 寫設備*/ 

10  ssize_t xxx_write(struct file *filp, const char __user *buf, size_t count, 

11      loff_t *f_pos) 

12  { 

13      ... 

14      copy_from_user(..., buf, ...); 

15      ... 

16  } 

17  /* ioctl 函數 */ 

18  int xxx_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 

19      unsigned long arg) 

20  { 

21      ... 

22      switch (cmd) { 

23      case XXX_CMD1: 

24            ... 

25            break; 

26      case XXX_CMD2: 

27            ... 

28            break; 

29      default: 

30            /* 不能支持的命令 */ 

31            return  - ENOTTY; 

32      } 

33      return 0; 

34  } 


設備驅動的讀函數中,filp 是文件結構體指針,buf 是用戶空間內存的地址,該地址在內核空

間不能直接讀寫,count 是要讀的字節數,f_pos 是讀的位置相對于文件開頭的偏移。

寫函數同理

由于內核空間與用戶空間的內存不能直接互訪,因此借助了函數 copy_from_user()完成用戶空間

到內核空間的拷貝,以及copy_to_user()完成內核空間到用戶空間的拷貝,見代碼第6行和第14行。

完成內核空間和用戶空間內存拷貝的 copy_from_user()和 copy_to_user()的原型分別為:

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

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

上述函數均返回不能被復制的字節數,因此,如果完全復制成功,返回值為 0。


在字符設備驅動中,需要定義一個 file_operations 的實例,并將具體設備驅動的函數賦值給

file_operations 的成員,例如:

1 struct file_operations xxx_fops = {

2 .owner = THIS_MODULE,

3 .read = xxx_read,

4 .write = xxx_write,

5 .ioctl = xxx_ioctl,

6 ...

7  }


關鍵字:Smart210  Linux 引用地址:Smart210學習記錄-------Linux設備驅動結構

上一篇:Smart210---LED驅動
下一篇:Smart210學習記錄-------文件操作

推薦閱讀最新更新時間:2025-04-17 21:28

u-boot移植(友善smart210開發板)
U-boot 源代碼下載: ftp://ftp.denx.de/pub/u-boot/ 啟動過程分析:1.小于8Kb的程序:IROM從nand讀8K數據到ISRAM中運行; 2.大于8kb程序(主要指u-boot):IROM從nand讀前8k數據到SRAM中主要做兩件事: 第一:初始化DRAM; 第二:將剩下的代碼搬運到DRAM運行。 3.在DRAM中就可以引導系統啟動了。 BL0:IROM,出廠已固化代碼 BL1:ISRAM的前16kb,u-boot-spl.bin BL2:ISRAM的后80kb,u-boot.bin ISRAM是內置內存,不用初始化就可以使用; DRAM是外接內存,需要初始化才能使用。 uboot有兩種模
[單片機]
Linux-3.0.8中基于S5PV210的GPIO模塊代碼追蹤和分析
編寫按鍵驅動時,想知道內核是如何管理GPIO的,所以開始追蹤代碼,中間走了一些彎路,現記錄于此。 追蹤代碼之前,我猜測:第一,這部分代碼應該在系統set up階段執行;第二,GPIO的代碼應該在machine或者platform或者vendor相關的目錄下。事實證明,第一點是正確的,第二點基本是錯誤的,因為內核依靠對GPIO的抽象來管理之,這層抽象層給具體的machine留出了一些它們需要是實現的接口,這與其他的設備驅動框架在使用上是很類似的,當然,GPIO也是一種設備啊... ...所以,管理GPIO的多數代碼位于drivers/gpio/目錄下。 好了,開始走讀代碼,那么對于S5PV210這塊SoC,GPIO子系統的入
[單片機]
Linux移植之auto.conf、autoconf.h、Mach-types.h的生成過程簡析
在Linux移植之make uImage編譯過程分析中分析了uImage文件產生的過程,在uImage產生的過程中,順帶還產生了其它的一些中間文件。這里主要介紹幾個比較關鍵的文件 1、linux-2.6.22.6includeconfigauto.conf、inux-2.6.22.6includelinuxautoconf.h文件的生成過程 2、includeasm-armMach-types.h文件的生成過程 1、inux-2.6.22.6includeconfigauto.conf、inux-2.6.22.6includelinuxautoconf.h文件的生成過程 在頂層Makefile中嘗試尋找auto.c
[單片機]
ARM-Linux移植之(二)——Linux2.6.22內核移植
平臺:mini2440 交叉工具鏈:arm-linux-gcc-4.3.2 一、內核移植基本知識 移植內核也叫構建BSP(boardsupprot packet)。BSP的作用有兩個:一是為內核運行提供底層支持,二是屏蔽與板相關的細節。 BSP的構建分三個層次 1、體系結構層次 對一些體系結提供linux內核支持,比如說ARM,X86等芯片。這一類工作一般在arc/xxx/下面額除了palt-xxx和mach-xxx目錄的其他目錄完成。 2、SOC層次 對一些公司提供的SOC微處理器提供linux內核支持,比如說三星公司的 S3C2440。這一類工作一般在arch/
[單片機]
linux-2.6.32在mini2440開發板上移植 移植I2C-EEPROM 驅動
1 在內核中配置I2C 驅動 Linux-2.6.32.2 對S2C2440 的I2C 接口提供了完善的驅動,因此我們只需在內核中配置一下即可使用。 在內核源代碼目錄執行:make menuconfig,進入內核配置主菜單,依次選擇進入如下子菜單: Device Drivers --- * I2C support --- I2C Hardware Bus support --- 如圖,我們看到這里已經選擇好了“ * S3C2410 I2C Driver”,這里的S3C2410 也可以適用于S3C2440,因為它們的I2C 端口及寄存器定義都是完全相同的。 以上配置所對
[單片機]
<font color='red'>linux</font>-2.6.32在mini2440開發板上移植 移植I2C-EEPROM 驅動
Linux下USB從(USB gadget) 驅動配置與使用
S3C2440提供了一個USB從接口,我們可以使用它來把2440模擬為一個U盤,直接從電腦上以盤符的形式訪問2440 一、內核配置 USB SUPPORT * USB Gadget Support --- USB Peripheral Controller (S3C2410 USB Device Controller) --- S3C2410 USB Device Controller S3C2410 udc debug messages M USB Gadget Drivers M File-backed Storage Gadget 二、make zImage 生成z?Im
[單片機]
Linux和qtopia下的矩陣鍵盤驅動程序
基于s3c2440和linux,實現了3*4的矩陣鍵盤驅動。 功能:延時消抖,重復按鍵,多鍵齊按(??) 更詳細的說明文檔:“基于S3C24440和嵌入式Linux的矩陣鍵盤設計”,電子技術,2008,45(5):21-23 /********************************************************** * s3c2440-keyboard.c * * keyboard driver for S3C2440 based PDA * * * History:2007/04/30 * * *********************************************
[單片機]
Linux高級驅動】觸摸屏驅動的移植
觸摸屏驅動的移植 流程 注意:看框架圖 1.添加input.c組件 Device Drivers --- Input device support --- Generic input layer (needed for keyboard, mouse, ...) 2.添加evdev.c組件 Device Drivers --- Input device support --- * Event interface 3.添加s3c2410_ts.c觸摸屏驅動 修改driver/input/touchscreen/Kconfig config TOUCHSCREEN_S3C2410 tristate Samsun
[單片機]
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 富民县| 彩票| 宁陕县| 榕江县| 安吉县| 晋江市| 英吉沙县| 环江| 景宁| 南充市| 天祝| 汝城县| 扎兰屯市| 吴忠市| 桐乡市| 新乡市| 阿合奇县| 襄垣县| 定兴县| 云梦县| 温泉县| 阜新市| 鹤壁市| 德兴市| 大埔县| 庆城县| 河间市| 长泰县| 蛟河市| 许昌县| 龙州县| 永登县| 曲松县| 碌曲县| 玛纳斯县| 普兰县| 都匀市| 获嘉县| 浙江省| 宁城县| 通化市|