linux驱动模型——platform(1)
一.驱动模型包含什么?
1.1. 类class
1.1.2. 它能够自动创建/dev下的设备节点,不需要mknod /dev/xxx c x x创建。当然class还有其另外的作用,且自动创建设备节点的还有udev系统,udev是处于用户空间的,其自动创建设备节点也是依赖于sysfs文件系统中提供的class类
1.2. 总线bus
1.2.1. 总线是处理器和设备之间的通道。总线有多种类型,每种总线可以挂载多个设备
1.3. 设备device
1.3.1. 驱动程序是在CPU运行时,提供操作的软件接口。所有的设备必须有与之配套驱动程序才能正常工作。一个驱动程序可以驱动多个类似或者完全不同的设备。
1.4. 驱动driver
1.4.1. 设备就是连接在总线上的物理实体。设备是有功能之分的。具有相同功能的设备被归到一个类,如输入设备(鼠标,键盘,游戏杆等)。
1.5. 三者的关系
1.5.1. 总线上有两个重要的链表:1)设备(device)链表;2)驱动(driver)链表
1.5.2. 每次出现一个设备就要向总线汇报,每次出现一个驱动,也要向总线注册。系统初始化的时候,会扫描连接了哪些设备,为每一个设备建立起一个struct device的变量,并加入设备链表;每次注册一个驱动,就要准备一个struct device_driver结构的变量,并加入驱动链表。这样所有的设备都挂载到总线上,当加载驱动时,驱动就去总线上找到自己对应的设备,或者先把驱动注册上,来了一个设备就去总线找驱动。如果只有设备却没有对应的驱动,那么设备无法工作,如果只有驱动却没有设备,驱动也起不了任何作用。
1.5.3. 每种总线下面可以挂载许多设备。(通过kset devices)
1.5.4. 每种总线下可以用很多驱动。(通过包含一个kset drivers)
1.5.5. 每个驱动可以处理一个或多个设备。
1.6. 其它内容
1.6.1. 对象的引用计数
1.6.1.1. 通常一个内核对象被创建时,不可能知道该对象存活的时间。跟踪此对象生命周期的一个方法是使用引用计数。当内核中没有代码持有该对象的引用时,该对象将结束自己的有效生命周期,并且可以被删除
1.6.2. sysfs表述sysfs表述
1.6.2.1. 在sysfs中显示的每一个对象,都对应一个kobject,它被用来与内核交互并创建它的可见表述。
1.6.2.2. 数据结构关联:从整体上看,设备模型是一个友好而复杂的数据结构,通过在其间的大量连接而构成一个多层次的体系结构。Kobject实现了该结构并把它们聚合在一起
1.6.3. uevent事件处理
1.6.3.1. 当系统中的硬件被热插拔时,在kobject子系统控制下,将产生事件以通知用户空间
1.6.3.2. Kobjects 在内核中对应有一套申请,初始化,添加,注册,计数操作,释放等函数
二. 为什么需要设备驱动模型
2.1. linux 2.6版本中正式引入设备驱动模型,目的是在设备越来越多,功耗要求等新特性要求的情况下让驱动体系更易用、更优秀。
2.2. 设备驱动模型负责统一实现和维护一些特性,诸如:电源管理、热插拔、对象生命周期、用户空间和驱动空间的交互等基础设施
2.3. 设备驱动模型目的是简化驱动程序编写,但是客观上设备驱动模型本身设计和实现很复杂
三. 驱动模型中重要结构体
3.1. kobject结构体
3.1.1. 定义在linux/kobject.h中
struct kobject {
const char *name; ///*kobject的名字,每个kobject都对应着sysfs下的一个文件夹,该名字也是对应的文件夹的名字。*/
struct list_head entry; ///*双向链表指针,用于将同一kset集合中的kobject链接到一起,便于访问*/
struct kobject *parent; ///*kobject对应的父kobject节点,在sysfs表现为上一级目录*/
struct kset *kset; ///*kobject所在的集合的指针,kset概念将在kset一节中描述*/
struct kobj_type *ktype; // /*kobject对象类型指针,随后将会介绍*/
struct sysfs_dirent *sd; // /*sd用于表示VFS文件系统的目录项,由此可见它是设备与文件之间的桥梁。在sysfs节会对此结构进行分析*/
struct kref kref; // /*对象引用计数器。
unsigned int state_initialized:;
unsigned int state_in_sysfs:;
unsigned int state_add_uevent_sent:;
unsigned int state_remove_uevent_sent:;
unsigned int uevent_suppress:;
};
3.2. kobj_type结构体
3.2.1. 很多书中简称为ktype,每一个kobject都需要绑定一个ktype来提供相应功能
3.2.2. 关键点1:sysfs_ops,提供该对象在sysfs中的操作方法(show和store)
3.2.3. 关键点2:attribute,提供在sysfs中以文件形式存在的属性,其实就是应用接口
struct kobj_type {
void (*release)(struct kobject *kobj);
const struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
const void *(*namespace)(struct kobject *kobj);
};
3.3. kset结构体
3.3.1. kset与kobject关系
/**
* struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
*
* A kset defines a group of kobjects. They can be individually
* different "types" but overall these kobjects all want to be grouped
* together and operated on in the same manner. ksets are used to
* define the attribute callbacks and other common events that happen to
* a kobject.
*
* @list: the list of all kobjects for this kset
* @list_lock: a lock for iterating over the kobjects
* @kobj: the embedded kobject for this kset (recursion, isn't it fun...)
* @uevent_ops: the set of uevent operations for this kset. These are
* called whenever a kobject has something happen to it so that the kset
* can add new environment variables, or filter out the uevents if so
* desired.
*/
struct kset {
struct list_head list;
spinlock_t list_lock;
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
};
3.4. bus_type结构体
3.4.1. match函数
3.4.1.1. match方法用来对总线下的device和driver进行匹配。理论上每种总线的匹配算法是不同的,但是实际上一般都是看name的
3.4.2. uevent函数
3.4.2.1. 产生事件以通知用户空间
struct bus_type {
const char *name;
struct bus_attribute *bus_attrs;
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs; int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev); const struct dev_pm_ops *pm; struct bus_type_private *p;
};
3.5. device结构体
3.5.1. struct device是硬件设备在内核驱动框架中的抽象,是所有设备共有部分的集合
3.5.2. device_register用于向内核驱动框架注册一个设备
3.5.3. 通常device不会单独使用,而是被包含在一个具体设备结构体中,如struct usb_device有struct device成员
struct device {
struct device *parent; struct device_private *p; struct kobject kobj;
const char *init_name; /* initial name of the device */
struct device_type *type; struct mutex mutex; /* mutex to synchronize calls to
* its driver.
*/ struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power; #ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */ struct device_dma_parameters *dma_parms; struct list_head dma_pools; /* dma pools (if dma'ble) */ struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
/* arch specific additions */
struct dev_archdata archdata;
#ifdef CONFIG_OF
struct device_node *of_node;
#endif dev_t devt; /* dev_t, creates the sysfs "dev" */ spinlock_t devres_lock;
struct list_head devres_head; struct klist_node knode_class;
struct class *class;
const struct attribute_group **groups; /* optional groups */ void (*release)(struct device *dev);
};
3.6. device_driver结构体
3.6.1. struct device_driver是驱动程序在内核驱动框架中的抽象
3.6.2. 关键元素1:name,驱动程序的名字,很重要,经常被用来作为驱动和设备的匹配依据
3.6.3. 关键元素2:probe,驱动程序的探测函数,用来检测一个设备是否可以被该驱动所管理
struct device_driver {
const char *name;
struct bus_type *bus; struct module *owner;
const char *mod_name; /* used for built-in modules */ bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ #if defined(CONFIG_OF)
const struct of_device_id *of_match_table;
#endif int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups; const struct dev_pm_ops *pm; struct driver_private *p;
};
参考《朱老师.linux设备驱动模型》
索引文献:https://blog.csdn.net/lindonghai/article/details/8111744
索引文献:https://blog.csdn.net/zhoujiaxq/article/details/7646050
linux驱动模型——platform(1)的更多相关文章
- linux驱动模型——platform(2)
一. platform 组织架构 1.1. platform工作体系都定义在drivers/base/platform.c中 1.2. platform相关函数声明在include/linux/pla ...
- Linux驱动模型解析bus之platform bus
这是内核启动之后要调用的驱动模型的开始代码: drivers/base/init.c/** * driver_init - initialize driver model. * * Call the ...
- 从串口驱动的移植看linux2.6内核中的驱动模型 platform device & platform driver【转】
转自:http://blog.csdn.net/bonnshore/article/details/7979705 写在前面的话: 博主新开了个人站点:你也可以在这里看到这篇文章,点击打开链接 本文是 ...
- Linux 驱动框架---platform驱动框架
Linux系统的驱动框架主要就是三个主要部分组成,驱动.总线.设备.现在常见的嵌入式SOC已经不是单纯的CPU的概念了,它们都会在片上集成很多外设电路,这些外设都挂接在SOC内部的总线上,不同与IIC ...
- linux驱动模型<输入子系统>
在linux中提供一种输入子系统的驱动模型,其主要是实现在input.c中. 在输入子系统这套模型中,他把驱动分层分类.首先分为上下两层,上层为input.c .下层为驱动的实现,下层分为两部分,一部 ...
- 总线设备驱动模型---platform篇
总线设备驱动模型----驱动篇 http://blog.chinaunix.net/uid-27664726-id-3334923.html http://blog.chinaunix.net/uid ...
- Linux设备驱动模型之platform(平台)总线详解
/********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...
- linux内核驱动模型
linux内核驱动模型,以2.6.32内核为例.(一边写一边看的,有点乱.) 1.以内核对象为基础.用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键.具有相同类型的内核对象构 ...
- linux设备模型_转
建议原博文查看,效果更佳. 转自:http://www.cnblogs.com/wwang/category/269350.html Linux设备模型 (1) 随着计算机的周边外设越来越丰富,设备管 ...
随机推荐
- ivew 封装删除 对话框
封装的组件 <template> <Modal footer-hide :closable="false" title="删除确认" v-mo ...
- bzoj5099 [POI2018]Pionek 双指针
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5099 题解 这道题做法似乎挺单一的. (一开始想了个假做法 向量和的长度等于所有向量在其方向上 ...
- 这两天老是有兄弟问到Vue的登陆和注册,登陆成功留在首页,没有登录回到登录页面,现在我用最简单实用的方法实现(两分钟技就看懂)
其实登录注册,并且登录一次保持登录的状态,是每个项目都需要实现的功能. 网上也有很多的方法,不过,不是通俗易懂,在这里说一下我自己的方法,非常简单实用核心就是用localStorage存.取数据,这样 ...
- 一、MyBatis基本使用,包括xml方式、注解方式、及动态SQL
一.简介 发展历史:MyBatis 的前 身是 iBATIS.最初侧重于 密码软件的开发 , 后来发展成为一款基于 Java 的持久层框架. 定 位:MyBatis 是一款优秀的支持自定义 ...
- JavaSE---泛型系统学习
1.概述 1.1.泛型: 允许在 定义 类.接口.方法时 使用 类型形参,这个类型形参 将在声明变量.创建对象.调用方法时 动态地指定: 1.2.jdk5后,引入了 参数化类型(允许程 ...
- Linux内核设计与实现 总结笔记(第十章)内核同步方法
一.原子操作 原子操作可以保证指令以原子的方式执行----执行过程不被打断. 1.1 原子整数操作 针对整数的原子操作只能对atomic_t类型的数据进行处理. 首先,让原子函数只接收atomic_t ...
- Bugku web 计算器
计算器 打开网页,想输入正确的计算结果发现只输进去一位数??? 遇事不决先F12看一眼源码,发现flag
- 约数定理(two)
筛约数个数和 理论基础: 1.对n质因数分解,n=p1^k1 * p2^k2 * p3^k3 …… 则n的约数个数为(k1+1)*(k2+1)*(k3+1)…… 2.线性筛素数时,用i和素数pj来筛掉 ...
- .NET(c#) 移动APP开发平台 - Smobiler(2) - 平台介绍
看到大家很多人在后台问我一些问题,所以准备写一个系列了,下面给个目录 目录: .NET(c#) 移动APP开发平台 - Smobiler(1) 环境的搭建及上手第一个应用 类似开发WinForm的方式 ...
- #1123-JSP隐含对象
JSP 隐含对象 JSP隐含对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明.JSP隐含对象也被称为预定义变量. JSP所支持的九大隐含对象: 对象,描述 reque ...