LINUX设备驱动模型简介

来源:互联网 发布:ubuntu ftp服务器配置 编辑:程序博客网 时间:2024/05/22 07:40

××××××××××××××LINUX设备驱动模型简介×××××××××××××××××

第一部分————————————————————————————————————-
1.linux设备驱动模型简介
2.设备驱动模型的底层架构:类,总线,设备,驱动,platform

3.实践:使用设备驱动模型来加载上一个led驱动

1.linux设备驱动模型简介
《1》什么是设备驱动模型将一个概念时怎样讲明白,直接以句话很难讲明白,从多个方面去讲,讲完以后你也就自然明白了:比如,描述一个人时,可以说他有一个儿子–你就知道他是一个父亲的角色,父母健在,老婆还在,也就知道是儿子角色,丈夫角色等等
a.
类class
总线bus : iic spi 等负责挂接驱动和设备
设备device:任何设备必然可以使××××××××××××××LINUX设备驱动模型简介×××××××××××××××××

第一部分————————————————————————————————————-
1.linux设备驱动模型简介
2.设备驱动模型的底层架构:类,总线,设备,驱动,platform

3.实践:使用设备驱动模型来加载上一个led驱动

1.linux设备驱动模型简介
《1》什么是设备驱动模型将一个概念时怎样讲明白,直接以句话很难讲明白,从多个方面去讲,讲完以后你也就自然明白了:比如,描述一用一个结构体来描述,cdev里的dev就是这个结构体
驱动driver<分别对应驱动里面的四个结构体>
用这四个结构体(四种模型)来生产一个实例
b.koject:结构体,代表一个kernelobject即内核的一个物体,一个高度抽象的结构体,表示内核里的一个对象

《4》设备驱动模型目地是简化驱动程序编写,但是客观上设备驱动模型本身设计和实现很复杂,如果只是利用设备驱动模型去写驱动,不难,但要理解本身的实现并不简单,像开车一样,开容易,研究如何造成就难,车越高级,使用越简单,但实现更难,只需要关注怎么用就是高手

3,设备驱动模型下去进行驱动开发的2个核心点
《1》驱动源码本身编写,调试(驱动源程序真正干活的函数,寄存器,怎样调节性能等,重点在于对硬件的了解,得对硬件很了解才能写这个驱动)
《2》别人写驱动什么时候被安装《insmod,需要自动调用,触摸屏一接上就要自动安装上,芯片拔掉就能自动卸载,这就需要能自动申请释放内存》,驱动中的函数什么时候被调用,而且应用程序怎么就操控这些(这些完全和设备驱动模型有关,和硬件无关),别人写好了驱动,我怎么实现开机就加载等—这个功能由内核中设备驱动模型来实现了
重点学习这个框架—将来出错了从哪几方面来调试,来思考

本节介绍linux设备驱动模型诞生的原应,技术特征,以及其对驱动开发编写调试的影响
主要目地是让大家全方位感受一下到底什么是linux的驱动设备模型
实现热插拔等就是通过总线实现

第二节:设备驱动模型的底层架构
1.kobject:他就相当于一个基类,它就是作为别的结构体里面的一个成员
《1》定义在linux/kobject.h中
《2》各种对象最基本单元,提供一些公用型服务如:对象引用计数(记录被几个对象同时引用,即几个对象的功能是基于我的,当为0时这个对象就可以被自动释放掉了),维护对象链表(驱动的链表,用于遍历,每个驱动里都进入一个进入低功耗的函数,当执行待机时就可以遍历调用每个驱动的待机函数),对象上锁(当前对象在执行一个重要操作时就可以上锁,解决竟态),对用户空间的表示(sysfs)
《3》设备驱动模型中的各种对象其内部都会包含一个kobject,为什么要包含,就是为了使用这些功能
《4》地位相当于面对对象体系结构中的总计类
structkobject {
constchar *name;
structlist_head entry; //内核链表
structkobject *parent; //完成此object和上下层的object直接的挂接
structkset *kset;
structkobj_type *ktype; //简称ktype
structsysfs_dirent *sd;
structkref kref; kernel refcount内核原子操作,用于对象引用技术
unsignedint state_initialized:1;
unsignedint state_in_sysfs:1;
unsignedint state_add_uevent_sent:1;
unsignedint state_remove_uevent_sent:1;
unsignedint uevent_suppress:1;
};

上下层用parent链表

平行层直接用listhead

structkref {
atomic_trefcount;//refconut原子操作
};
2.kobj_type对用户空间的表示
structkobj_type {
void(*release)(structkobject *kobj);
conststruct sysfs_ops* sysfs_ops;
structattribute **default_attrs;
conststruct kobj_ns_type
}
《1》很多书中简称为ktype,每一个kobject都需要绑定(而不是包含,即里面不包含这个结构体对象,但是可以找到(就是通过指针,包含一个指针))一个ktype来提供相应功能
《2》关键点1:sysfs_ops,提供sysfs中以文件形式存在的属性,起始就是应用接口
《3》关键点2:attribute,提供在sysfs中以文件形式存在的属性,起始就是应用接口
3.kset
**
*struct kset - a set of kobjects of a specific type, belonging to aspecific subsystem.
*
*A kset defines a group of kobjects. They can be individually
*different “types” but overall these kobjects all want to begrouped
*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 itfun…)
*@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.
*/
structkset {
structlist_head list;
spinlock_tlist_lock;
structkobject kobj;
conststruct kset_uevent_ops *uevent_ops;
};

kset就是用来实现这种文件系统的上下级分层关系,了解可以了,会用
/sys

device input class …

《1》kset的主要作用是做顶层kobject的容器类
《2》kset的主要目地是将各个kobject(代表着各个对象)组织出目录层次架构
《3》可以认为kset就是在sysfs中弄出目录,从而让设备驱动模型中的多个对象能够有层次有逻辑性的组织在一起

—————————这三个就实现了sysfs虚拟文件系统的所有结构——————–了解即可——————–

下层和上层之间的关系,就是下层为上层提供一些功能,用封装成函数的方式,让上层去调用

第三节:总线式设备驱动组织方式
1.总线:物理上真实的总线衍生出来的,譬如大楼需要供电,就有一个很粗的电线把电引进去,再在每一层引出去各个电路以实现每户的供电

PCI总线,iiC总线

《1》物理上的真实总线及其作用(总线就是用来传输和连接的)
《2》驱动框架中的总线式设计(思路:内核里面面临问题,管控很多设备和驱动—CPU连接了多个设备多个通道,而每个通道设备有连接了多个设备,而每一个设备就需要一个对应的驱动,但是需要实现热插拔,插入则装驱动,拔下则卸载掉驱动,所以操作系统为了管理这些设备和驱动,就发明了总线式驱动管理机制–总线的管理思路-首先操作系统创建一些总线,然后操作系统把这些总线管理好就可以了,然后总线再去管理具体的设备,如usb总线管理usb设备和驱动,用链表来连接,如usb插入,则添加一个设备节点到bus总线,对应的驱动到usb总线驱动上去找,如果找到则正常工作,如果没找到,就可以向操作系统上报这个家伙是个异类,需要重新编写驱动)
《3》bus_type结构体,关键是match函数和uevent函数
/**
*struct bus_type - The bus type of the device
*
*@name: The name of the bus.
*@dev_name: Used for subsystems to enumerate devices like (“foo%u”,dev->id).
*@dev_root: Default device to use as the parent.
*@bus_attrs: Default attributes of the bus.
*@dev_attrs: Default attributes of the devices on the bus.
*@drv_attrs: Default attributes of the device drivers on the bus.
*@match: Called, perhaps multiple times, whenever a new device ordriver
* isadded for this bus. It should return a nonzero value if the
* givendevice can be handled by the given driver.
*@uevent: Called when a device is added, removed, or a few otherthings
* thatgenerate uevents to add the environment variables.
*@probe: Called when a new device or driver add to this bus, andcallback
* thespecific driver’s probe to initial the matched device.
*@remove: Called when a device removed from this bus.
*@shutdown: Called at shut-down time to quiesce the device.
*@suspend: Called when a device on this bus wants to go to sleep mode.
*@resume: Called to bring a device on this bus out of sleep mode.
*@pm: Power management operations of this bus, callback the specific
* devicedriver’s pm-ops.
*@iommu_ops: IOMMU specific operations for this bus, used to attachIOMMU
* driver implementations to a bus and allow the driver todo
* bus-specific setup
*@p: The private data of the driver core, only the driver core can
* touchthis.
*
*A bus is a channel between the processor and one or more devices. Forthe
*purposes of the device model, all devices are connected via a bus,even if
*it is an internal, virtual, “platform” bus. Buses can pluginto each other.
*A USB controller is usually a PCI device, for example. The devicemodel
*represents the actual connections between buses and the devices theycontrol.
*A bus is represented by the bus_type structure. It contains the name,the
*default attributes, the bus’ methods, PM operations, and the drivercore’s
*private data.
*/
structbus_type {
constchar *name; //总线名称,注册了之后可以在/sys/bus下可以看到
constchar *dev_name; //
structdevice *dev_root;
structbus_attribute *bus_attrs;
structdevice_attribute *dev_attrs;
structdriver_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);

conststruct dev_pm_ops *pm; //电源管理

structiommu_ops *iommu_ops;

structsubsys_private *p;
structlock_class_key lock_key;
};

2.设备(总线下面的设备)device为设备结构体里的一个基类,所有设备的共性
《1》structdevice是硬件设备在内核驱动框架中的抽象,每个该结构体类型的变量就对应一个具体的设备
《2》device_register用于向内核驱动框架注册一个设备(设备名,gpio号,中断号等等等)
《3》通常device结构体不会单独使用,儿时被包含在一个具体设备结构中,如structusb_devce
3.驱动structdevice_driver
structdevice_driver {
constchar *name; //这个name非常重要,用于设备和驱动的匹配,如dts中每个设备都用.compatible来获取到设备名,再在驱动里的name来和其相匹配
structbus_type *bus;

structmodule *owner;
constchar mod_name; / used for built-in modules */

boolsuppress_bind_attrs; /* disables bind/unbind via sysfs */

conststruct of_device_id *of_match_table;
conststruct acpi_device_id *acpi_match_table;

int(*probe) (struct device*dev); //探测,每一个驱动都有探测函数,非常重要,但总线式框架才需要,非总线式不需要(但总线式为一个趋势),总线式驱动的probe函数用来检测一个设备是否可以被该区动管理,当驱动程序执行时,继续考虑设备跟驱动能不能匹配,即能不能跟设备配对,他就是总线式驱动的入口函数
int(*remove) (struct device *dev);
void(*shutdown) (struct device *dev);
int(*suspend) (struct device *dev, pm_message_t state);
int(*resume) (struct device *dev);
conststruct attribute_group **groups;

conststruct dev_pm_ops *pm;

structdriver_private *p;
};
《1》structdevice_driver是驱动策划嗯需在内核驱动框架中的抽象
《2》关键元素1,name:驱动程序的名字,很重要,经常备用来作为驱动和设备的匹配依据、
《3》关键元素2probe:驱动程序的探测函数,用来检测一个设备是否可以被该驱动所管理

–———————总线设备驱动是一套整体——————————-
4.类:
《1》相关结构体structclass和 structclass_device
《2》udev(就是热插拔功能)的使用离不开class
《3》class的真正意义在于作为同于一个class的多个设备的容器,也就是说,class是一种人造概念,目地就是为了对各种设备进行分类管理,当然,class在分类的同时还对每个类贴上了一些标签,这也是设备驱动模型为我们写驱动提供的基础设施
/sys/bus/*都是一些符号链接,连接到/sys/devices下

5总结
(1)模型思想很重要,起始就是面对对象的思想
(2)全市结构体套结构体,对基本功(语言功底和大脑的复杂度,把大量跳转的代码联系起来)要求很高

0 0
原创粉丝点击