linux内核部件分析设备驱动模型之busWord文档下载推荐.docx
- 文档编号:21339536
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:22
- 大小:25.53KB
linux内核部件分析设备驱动模型之busWord文档下载推荐.docx
《linux内核部件分析设备驱动模型之busWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《linux内核部件分析设备驱动模型之busWord文档下载推荐.docx(22页珍藏版)》请在冰豆网上搜索。
*env);
9.
(*probe)(struct
*dev);
10.
(*remove)(struct
11.
void
(*shutdown)(struct
12.
13.
(*suspend)(struct
pm_message_t
state);
14.
(*resume)(struct
15.
16.
dev_pm_ops
*pm;
17.
18.
bus_type_private
*p;
19.};
structbus_type是bus的通用数据结构。
name是bus的名称,注意到这里也是constchar类型的,在sysfs中使用的还是kobj中动态创建的名称,这里的name只是初始名。
bus_attrs是bus为自己定义的一系列属性,dev_attrs是bus为旗下的device定义的一系列属性,drv_attrs是bus为旗下的driver定义的一系列属性。
其中dev_attrs在bus_add_device()->
device_add_attrs()中被加入dev目录下,drv_attrs在bus_add_driver()->
driver_add_attrs()中被加入driver目录下。
match函数匹配总线中的dev和driver,返回值为1代表匹配成功,为0则失败。
uevent函数用于总线对uevent的环境变量添加,但在总线下设备的dev_uevent处理函数也有对它的调用。
probe函数是总线在匹配成功时调用的函数,bus->
probe和drv->
probe中只会有一个起效,同时存在时使用bus->
probe。
remove函数在总线上设备或者驱动要删除时调用,bus->
remove和drv->
remove中同样只会有一个起效。
shutdown函数在所有设备都关闭时调用,即在core.c中的device_shutdown()函数中调用,bus->
shutdown和drv->
shutdown同样只会有一个起效。
suspend函数是在总线上设备休眠时调用。
resume函数是在总线上设备恢复时调用。
pm是structdev_pm_ops类型,其中定义了一系列电源管理的函数。
p是指向bus_type_private的指针,其中定义了将bus同其它组件联系起来的变量。
kset
subsys;
*drivers_kset;
*devices_kset;
klist
klist_devices;
klist_drivers;
blocking_notifier_head
bus_notifier;
unsigned
drivers_autoprobe:
1;
*bus;
10.};
12.#define
to_bus(obj)
container_of(obj,
bus_type_private,
subsys.kobj)
structbus_type_private是将bus同device、driver、sysfs联系起来的结构。
subsys是kset类型,代表bus在sysfs中的类型。
drivers_kset代表bus目录下的drivers子目录。
devices_kset代表bus目录下地devices子目录。
klist_devices是bus的设备链表,klist_drivers是bus的驱动链表。
bus_notifier用于在总线上内容发送变化时调用特定的函数,这里略过。
driver_autoprobe标志定义是否允许device和driver自动匹配,如果允许会在device或者driver注册时就进行匹配工作。
bus指针指向structbus_type类型。
使用structbus_type_private可以将structbus_type中的部分细节屏蔽掉,利于外界使用bus_type。
driver_private和structdevice_private都有类似的功能。
attribute
attr;
ssize_t
(*show)(struct
*bus,
*buf);
(*store)(struct
*buf,
size_t
count);
5.};
7.#define
BUS_ATTR(_name,
_mode,
_show,
_store)
\
8.struct
bus_attr_##_name
=
__ATTR(_name,
10.#define
to_bus_attr(_attr)
container_of(_attr,
bus_attribute,
attr)
structbus_attribute是bus对structattribute类型的封装,更方便总线属性的定义。
1.static
bus_attr_show(struct
kobject
*kobj,
*attr,
*buf)
3.{
*bus_attr
to_bus_attr(attr);
*bus_priv
to_bus(kobj);
ret
0;
if
(bus_attr->
show)
bus_attr->
show(bus_priv->
bus,
buf);
return
ret;
11.}
13.static
bus_attr_store(struct
count)
15.{
19.
20.
store)
21.
store(bus_priv->
buf,
22.
23.}
24.
25.static
sysfs_ops
bus_sysfs_ops
26.
.show
bus_attr_show,
27.
.store
bus_attr_store,
28.};
29.
30.static
kobj_type
bus_ktype
31.
.sysfs_ops
&
bus_sysfs_ops,
32.};
以上应该是我们最熟悉的部分,bus_ktype中定义了bus对应的kset应该使用的kobj_type实例。
与此类似,driver使用的是自定义的driver_ktype,device使用的是自定义的device_ktype。
只是这里仅仅定义了sysfs_ops,并未定义release函数,不知bus_type_private打算何时释放。
1.int
bus_create_file(struct
*attr)
2.{
error;
(bus_get(bus))
error
sysfs_create_file(&
bus->
p->
subsys.kobj,
attr->
attr);
bus_put(bus);
}
else
-EINVAL;
10.}
12.void
bus_remove_file(struct
13.{
sysfs_remove_file(&
18.}
bus_create_file()在bus目录下创建属性文件,bus_remove_file()在bus目录下删除属性文件。
类似的函数在driver和device中都有见到。
bus_uevent_filter(struct
*kset,
*kobj)
*ktype
get_ktype(kobj);
(ktype
==
bus_ktype)
8.}
10.static
kset_uevent_ops
bus_uevent_ops
.filter
bus_uevent_filter,
12.};
14.static
*bus_kset;
可以看到这里定义了一个bus_uevent_ops变量,这是kset对uevent事件处理所用的结构,它会用在bus_kset中。
__init
buses_init(void)
bus_kset
kset_create_and_add("
bus"
bus_uevent_ops,
NULL);
(!
bus_kset)
-ENOMEM;
7.}
在buses_init()中创建了/sys/bus目录,这是一个kset类型,使用了bus_uevent_ops的uevent操作类型。
其实这里的操作不难想象,在devices中我们有一个类似的devices_kset,可以回顾一下。
device_uevent_ops
dev_uevent_filter,
.name
dev_uevent_name,
.uevent
dev_uevent,
7./*
to
create
/sys/devices/
*/
10.int
devices_init(void)
11.{
devices_kset
devices"
device_uevent_ops,
...
14.}
16.void
device_initialize(struct
*dev)
17.{
dev->
kobj.kset
devices_kset;
20.}
devices_kset在devices_init()中被创建,使用相应的device_uevent_ops进行uevent处理。
而devices_kset又被设为每个device初始化时使用的kset。
这就不难想象每个device都是以devices_kset为所属kset的,并使用device_uevent_ops中的处理函数。
只是这里还不知bus_kset会在哪里用到,或许是每个bus所属的kset吧,下面会有答案。
show_drivers_autoprobe(struct
sprintf(buf,
"
%d\n"
drivers_autoprobe);
4.}
6.static
store_drivers_autoprobe(struct
8.{
(buf[0]
'
0'
)
drivers_autoprobe
count;
16.static
store_drivers_probe(struct
18.{
*dev;
dev
bus_find_device_by_name(bus,
NULL,
dev)
23.
-ENODEV;
(bus_rescan_devices_helper(dev,
NULL)
!
0)
25.
27.}
28.
29.static
BUS_ATTR(drivers_probe,
S_IWUSR,
store_drivers_probe);
BUS_ATTR(drivers_autoprobe,
S_IWUSR
|
S_IRUGO,
show_drivers_autoprobe,
store_drivers_autoprobe);
这里定义了总线下的两个属性,只写得drivers_probe,和可读写的drivers_autoprobe。
至于其怎么实现的,我们现在还不关心。
add_probe_files(struct
*bus)
retval;
retval
bus_create_file(bus,
bus_attr_drivers_probe);
(retval)
goto
out;
bus_attr_drivers_autoprobe);
bus_remove_file(bus,
12.out:
remove_probe_files(struct
add_probe_files()在bus目录下添加drivers_probe和drivers_autoprobe文件。
remove_probe_files()在bus目录下删除drivers_probe和drivers_autoprobe文件。
这两个函数对bus的probe类型属性进行管理,就像add_bind_files/remove_bind_files对driver的bind类型属性进行管理一样。
bus_uevent_store(struct
enum
kobject_action
action;
(kobject_action_type(buf,
count,
action)
kobject_uevent(&
action);
9.}
BUS_ATTR(uevent,
bus_uevent_store);
上面定义了bus的一个属性uevent,用于bus所在的kset节点主动发起uevent消息。
同样地uevent文件在driver目录中也有见到。
device目录中也有,不过除了store_uevent之外,还增加了show_uevent的功能。
*next_device(struct
klist_iter
*i)
klist_node
*n
klist_next(i);
*dev
NULL;
device_private
*dev_prv;
(n)
dev_prv
to_device_private_bus(n);
dev_prv->
device;
dev;
12.}
14.int
bus_for_each_dev(struct
*start,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 内核 部件 分析 设备 驱动 模型 bus