博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
device_driver结构体
阅读量:4046 次
发布时间:2019-05-25

本文共 3757 字,大约阅读时间需要 12 分钟。

一、定义:

struct device_driver结构体被定义在/include/linux/device.h,原型是:

struct  {
const char * ; struct * ; struct ; struct ; struct ; struct * ; const char * ; /* used for built-in modules */ struct * ; int (*) (struct * ); int (*) (struct * ); void (*) (struct * ); int (*) (struct * , ); int (*) (struct * );};

二、作用:描述设备驱动程序模型中的驱动程序。三、各字段详解:1、char* name; 设备驱动程序的名称。在调用driver_register()往设备驱动程序模型中插入一个新的device_driver对象时, driver_register()函数会调用bus_add_driver()函数,bus_add_driver()调用kobject_set_name()函数将 name赋给drv>kobj.name或者drv->kobj.k_name。注:drv为要调用driver_register()注册的device_driver类型的对象。2、struct bus_type *bus;指向总线描述符的指针,总线连接所支持的设备。此处我的理解是连接的是所有可使用该驱动程序驱动的 设备。3、struct kobject kobj;内嵌的kobject结构。最主要的作用还是使用它包含的引用计数器kref记录device_driver对象的使用情况。4、struct module *owner;     const char *mod_name;     struct module_kobject *mkobj;表示实现设备驱动程序的模块。也就是在该驱动的实现中,如果使用了模块,那么该域就指向你所写的模 块,并使用mod_name域指向模块名。如果没有使用模块,那该域就为空。还有该结构中的 module_kobject类型的mkobj也是与owner有关的域。 5、 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);

这五个回调函数用于处理热插拔、即插即用和电源管理。

当总线设备驱动程序发现一个可能有它处理的设备时就会调用probe方法,相应的函数将会探测硬件, 从而对该设备进行更进一步的检查。如果该device_driver对象的pribe()方法的返回值是一个负数,那就意 味这该驱动不能邦定到此设备上,那么就要释放所有为该device_driver对象分配的资源。      当移走一个可热插拔的设备时驱动程序会调用remove方法,而驱动程序本身被卸载时,它所处理的每 个设备也会调用remove方法。       当内核必须更改设备的供电状态时,设备驱动会调用shutdown、suspend和resume三个方法。其中 shutdown方法会停止对设备供电。suspend方法是将设备切换到低功耗状态,此方法中的state参数即要 设置的状态,pm_message_t被定义在linux/include/linux/pm.h中, typedef struct pm_message {
int event; }pm_message_t;

 

可取的状态有: #define PM_EVENT_ON 0   /*驱动器恢复工作,开始相应硬盘和软件请求*/ #define PM_EVENT_FREEZE 1  /*停止对设备的操作以便保存一致的映象,但是不能再进入低功耗状态,也不能发出唤醒事件*/ #define PM_EVENT_SUSPEND 2 /*为即将到来的系统状态进入低功耗状态,在适当的时候可以唤醒*/ #define PM_EVENT_PRETHAW 3 /*为系统从一个较早的PM_EVENT_FREEZE保存的映象中恢复过来 做准备*/ 更多关于 pm_message_t的解释参见 由低功耗状态唤醒设备就要调用resume方法。 四、操作函数:

1、driver_register()函数:/linux/drivers/base/driver.c
int (struct  * ){
if ((->-> && ->) || (->-> && ->) || (->-> && ->)) {
( "Driver '%s' needs updating - please use bus_type methods/n", ->); } (&->, , ); return ();}

函数首先是检查device_driver类型的drv对象和其bus域的回调函数是否已经被赋值,如果为空,则打印警告。 核心的注册是调用bus_add_driver()函数实现。在bus_add_driver()函数中,首先是检查drv->bus,如果为空 可立即返回EINVAL(无效的变量),注册失败,可见bus域必须提前初始化好才行。接下来是对kobj域进行初始 化,检查bus域等。最后调用add_bind_files()函数(实际上是由add_bind_files()函数调用driver_create_file()函 数)在sys文件系统下为其创建一个新的目录。

2、driver_register()函数:/linux/drivers/base/driver.c

 

/linux/drivers/base/driver.cvoid (struct  * ){
();}/linux/drivers/base/bus.cvoid (struct * ){
if (!->) return; (); (->, ); (&->); ("bus %s: remove driver %s/n", ->->, ->); (); (); (&->); (->);}

 

在bus_remove_driver()函数中首先是检查要卸载的device_driver类型的对象drv的bus域,如果为空则返回。 此种情况会发生在调用driver_register()函数注册drv时没有检查返回值,注册失败,但程序依然向下运行,到 driver_unregister()时就会到688行处返回。接下来会删除在调用driver_register()函数注册时在sys文件系统中 创建的目录,然后删除drv对象的属性,(属性是记录在文件中的,删除属性其实是删除记录drv->bus属性的文 件),删除驱动模块,减少对drv->bus的引用计数等。 3、get_driver()和put_driver()函数: 分别是增加和减少对该device_drvier类型的对象的引用计数。 4、int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) ;      void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr); 分别是在sys文件系统中为device_driver对象创建和删除目录。 五、参考: Understanding the linux kernel

转载地址:http://ctkci.baihongyu.com/

你可能感兴趣的文章
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>
Java中数字转大写货币(支持到千亿)
查看>>
Java.nio
查看>>
函数模版类模版和偏特化泛化的总结
查看>>
VMware Workstation Pro虚拟机不可用解决方法
查看>>
最简单的使用redis自带程序实现c程序远程访问redis服务
查看>>
redis学习总结-- 内部数据 字符串 链表 字典 跳跃表
查看>>
iOS 对象序列化与反序列化
查看>>
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>
iOS QQ侧滑菜单(高仿)
查看>>
iOS 扫一扫功能开发
查看>>
iOS app之间的跳转以及传参数
查看>>
iOS __block和__weak的区别
查看>>
Android(三)数据存储之XML解析技术
查看>>