04 Linux字符设备驱动

一、结构体

1. 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 };

2. file_operations 结构体

 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, unsigned long, unsigned long);
41   /* 在当前进程地址空间找到一个未映射的内存段 */
42   int(*check_flags)(int);
43   /* 允许模块检查传递给 fcntl(F_SETEL...)调用的标志 */
44   int(*dir_notify)(struct file *filp, unsigned long arg);
45   /* 对文件系统有效,驱动程序不必实现*/
46   int(*flock)(struct file *, int, struct file_lock*);
47   ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
48   /* 由 VFS 调用,将管道数据粘接到文件 */
49   ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
50   /* 由 VFS 调用,将文件数据粘接到管道 */
51   int (*setlease)(struct file *, long, struct file_lock **);
52 };
时间: 2024-08-25 04:21:23

04 Linux字符设备驱动的相关文章

linux字符设备驱动

一.字符设备.字符设备驱动与用户空间访问该设备的程序三者之间的关系. 如图,在Linux内核中使用cdev结构体来描述字符设备,通过其成员dev_t来定义设备号(分为主.次设备号)以确定字符设备的唯一性.通过其成员file_operations来定义字符设备驱动提供给VFS的接口函数,如常见的open().read().write()等. 在Linux字符设备驱动中,模块加载函数通过register_chrdev_region( ) 或alloc_chrdev_region( )来静态或者动态获

深入理解Linux字符设备驱动

文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解. 本文整合之前发表的<Linux字符设备驱动剖析>和<Linux 设备文件的创建和mdev>两篇文章,基于linux字符设备驱动的所有相关知识给读者一个完整的呈现. 一.从最简单的应用程序入手 1.很简单,open设备文件,read.write.ioctl,最后close退出.如下: 二./dev目录与文

(57)Linux驱动开发之三Linux字符设备驱动

1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是:这种三层的裸机驱动模型是足够满足低耦合.高内聚的特点的. 3.当有操作系统存在时,设备驱动成为了连接硬件和内核的桥梁,这时候的设备驱动对外表现为操作系统的API,与直接裸机开发不同,裸机开发时的设备驱动是应用工程师的API.如果设备驱动都按照操作系统给出的独立于设备的接口而设计,应用程序将可以使用统

Linux字符设备驱动实现

Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进行聊天 主要过程 实现 字符驱动设备 /* 参考:深入浅出linux设备驱动开发 */ #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <asm/uacc

linux 字符设备驱动开发详解

一.设备的分类及特点 1.字符设备 字符设备是面向数据流的设备,没有请求缓冲区,对设备的存取只能按顺序按字节的存取而不能随机访问.    Linux下的大多设备都是字符设备.应用程序是通过字符设备节点来访问字符设备的.通常至少需要实现 open, close, read, 和 write 等系统调用.    设备节点一般都由mknod命令都创建在/dev目录下,包含了设备的类型.主/次设备号以及设备的访问权限控制等,如:crw-rw----  1 root  root 4, 64 Feb 18

Linux字符设备驱动剖析

一.先看看设备应用程序 1.很简单,open设备文件,read.write.ioctl,最后close退出.如下: intmain(int argc ,char *argv[]){ unsigned char val[1] = 1; int fd =open("/dev/LED",O_RDWR);//打开设备 write(fd,val,1);//写入设备,这里代表LED全亮 close(fd);//关闭设备 return 0; } 二./dev目录与文件系统 2./dev是根文件系统下

Linux字符设备驱动框架

字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l /dev的时候,就能看到大量的设备文件,c就是字符设备,b就是块设备,网络设备没有对应的设备文件.编写一个外部模块的字符设备驱动,除了要实现编写一个模块所需要的代码之外,还需要编写作为一个字符设备的代码. 驱动模型 Linux一切皆文件,那么作为一个设备文件,它的操作方法接口封装在struct fi

Linux字符设备驱动注册流程

其中一部分从伯乐在线和网络上摘抄的内容,不用于商业用途. 一.linux系统将设备分为3类:字符设备.块设备.网络设备. 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流的设备,常见的字符设备有鼠标.键盘.串口.控制台和LED设备等. 块设备:是指可以从设备的任意位置读取一定长度数据的设备.块设备包括硬盘.磁盘.U盘和SD卡等. 每一个字符设备或块设备都在/d ev目录下对应一个设备文件.linux用户程序通过设备文件(或

Linux字符设备驱动开发的一般方法

.output_wrapper pre code { font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; overflow: auto !important } .output_wrapper a:hover { text-decoration: underline; color: rgb(0, 96, 100) } .out