Linux设备驱动之字符设备(二)
来源:互联网 发布:手机淘宝好评率 编辑:程序博客网 时间:2024/05/21 09:55
通过上一节Linux设备驱动字符设备(一)了解了Linux设备驱动的分类,设备号的构成,设备号的申请以及设备号的释放。
在Linux内核中使用struct cdev结构来代码字符设备。
<include/linux/cdev.h>--------------------------------------------------struct cdev { struct kobject kobj; struct module *owner; const struct file_operations *ops; struct list_head list; dev_t dev; unsigned int count;};
大概解释一下struct cdev结构中成员,在以后会详细说明其作用。
struct kobject kobj
内核的内嵌对象,是Linux设备驱动模型的重要成员。
struct module *owner
字符设备驱动程序所在的内核模块指针
struct file_operations *ops
字符设备驱动程序文件操作函数集,是应用程序通过文件系统访问驱动的桥梁。
struct list_head
用来将系统中字符设备形成的链表
dev_t dev
字符设备的设备号,由主次设备号组成
unsigned int count
次设备号的个数,用于表示驱动程序管理的同类设备的个数。
字符设备的分配
字符设备的分配也就是struct cdev的分配,内核一般有两组方式。
- 静态分配
static struct cdev chr_dev;
- 动态分配
内核提供一个函数,专门用来动态分配cdev结构
<fs/char_dev.c>----------------------------------------------------/** * cdev_alloc() - allocate a cdev structure * * Allocates and returns a cdev structure, or NULL on failure. */struct cdev *cdev_alloc(void){ struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { INIT_LIST_HEAD(&p->list); kobject_init(&p->kobj, &ktype_cdev_dynamic); } return p;}
可以看到是通过kzalloc分配一个struct cdev结构,并将此结构返回。
字符设备的初始化
既然分配一个struct cdev, 紧接着需要初始化struct cdev结构。内核同时也提供一个专门用来初始化struct cdev的函数cdev_init。
<fs/char_dev.c>-----------------------------------------------------------/** * cdev_init() - initialize a cdev structure * @cdev: the structure to initialize * @fops: the file_operations for this device * * Initializes @cdev, remembering @fops, making it ready to add to the * system with cdev_add(). */void cdev_init(struct cdev *cdev, const struct file_operations *fops){ memset(cdev, 0, sizeof *cdev); INIT_LIST_HEAD(&cdev->list); kobject_init(&cdev->kobj, &ktype_cdev_default); cdev->ops = fops;}
可以看到调用cdev_init,驱动程序需要传入file_operations结构的。
字符设备的注册
在前面知道了如何分配字符设备,以及初始化。接下来的任务就是将字符设备注册到系统中去。内核提供了cdev_add函数,用来将一个字符设备加入到系统中。
<fs/char_dev.c>---------------------------------------------------------------------/** * cdev_add() - add a char device to the system * @p: the cdev structure for the device * @dev: the first device number for which this device is responsible * @count: the number of consecutive minor numbers corresponding to this * device * * cdev_add() adds the device represented by @p to the system, making it * live immediately. A negative error code is returned on failure. */int cdev_add(struct cdev *p, dev_t dev, unsigned count){ int error; p->dev = dev; p->count = count; error = kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); if (error) return error; kobject_get(p->kobj.parent); return 0;}
此函数就是将一个字符设备加入到系统中去。第一个参数p代表加入到系统的字符设备的指针,第二个参数dev代表该设备的设备号,第三个参数count代表次设备的个数。
函数主要的部分kobj_map实现了如何将一个字符设备加入到系统的。该部分在后面Linux字符设备框架一节会详细分析,目前只要明白主要流程即可。
字符设备的注销
当驱动程序需要从系统卸载的时候,就需要使用cdev_del释放字符设备占用的内存。
<fs/char_dev.c>----------------------------------------------------------/** * cdev_del() - remove a cdev from the system * @p: the cdev structure to be removed * * cdev_del() removes @p from the system, possibly freeing the structure * itself. */void cdev_del(struct cdev *p){ cdev_unmap(p->dev, p->count); kobject_put(&p->kobj);}
此函数就是从卸载一个字符设备,参数p代表的是字符设备的指针。
目前为止,已经了解了设备号,设备号的构成,字符设备分配,字符设备的初始化,字符设备的注册以及字符设备的注销。将在下一节通过一个简单的字符设备驱动程序来再次熟悉整个流程,然后总结字符设备驱动的编写模型。
- linux设备驱动(二)---字符设备之按键驱动
- Linux 设备驱动之字符设备(二)
- Linux 设备驱动之字符设备(二)
- Linux设备驱动之字符设备(二)
- Linux设备驱动(二)字符设备
- 设备驱动之二----字符设备驱动
- Linux设备驱动之《字符设备驱动》
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- linux设备驱动之字符设备驱动
- Linux驱动模型学习(二)---字符设备驱动模型之二---初窥字符设备驱动
- Linux字符设备驱动(二)
- linux字符设备驱动框架(二)
- Linux字符设备驱动(二)
- Linux字符设备驱动(二)
- 收录几段DEP方法后置脚本
- GoldenGate、DataGuard与Stream Replication在数据同步和迁移方面的区别—理论篇
- 开发中查看日志的几个基本的Linux命令
- Android 在 Multidex 下使用 Instant Run
- 项目经理问:我怎么有做不完的事情-事件篮方法
- Linux设备驱动之字符设备(二)
- [线段树]Fowerpot
- 8 个最优秀的 Android Studio 插件
- TTS从9.2.0.4 迁移至11.2.0.3实现跨版本迁移数据一例 — 示例篇
- 云计算论文
- TCP/IP、Http、Socket的区别
- android-async-http
- java.lang.UnsatisfiedLinkError: No implementation found for long com.baidu.platform.comjni.map.commo
- AIX文件系统错误处理—示例篇