您的位置 首页 嵌入式

总线设备驱动模型总结

我的环境:主机开发环境:Fedora14开发板:TQ2440编译器:arm-linux-gcc-432总线设备驱动模型其实现主要是基于Kobject和sysf

我的环境:

主机开发环境:Fedora14
开发板: TQ2440
编译器: arm-linux-gcc-4.3.2
总线设备驱动模型其完结首要是根据Kobject和sysfs等机制,关于驱动模型程序开发首要是了解三个元素:总线、设备、驱动的联络。三者之间因为必定的联络性完结对设备的操控。
首要是总线,总线是三者联络起来的根底,经过一种总线类型,将设备和驱动联络起来。总线类型中的match函数用来匹配设备和驱动。当匹配操作晚餐之后就会操控驱动程序中的probe函数。
总线设备驱动模型的规划首要包含三个元素的注册,将三个元素加载到内核中,然后经过内核的内部机制将三者联络起来。
首要,总线类型的注册,包含特点文件的增加,总线也是一种设备,也需求将总线设备注册。
其次,完结设备的注册和增加以及对设备增加设备特点文件,一起填充最基本的函数操作。
最终,完结驱动的注册和天极以及对设备驱动增加特点文件,一起填充最基本的函数操作。
1、总线
总线类型是经过结构体bus_type表明的。其源码如下所示:
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 (*suspend_late)(struct device *dev, pm_message_t state);
int (*resume_early)(struct device *dev);
int (*resume)(struct device *dev);
struct dev_pm_ops *pm;
struct bus_type_private *p;
};
其间的int (*match)(struct device * dev, struct device_driver * drv)是有必要完结的函数,因为这个函数首要是完结设备和驱动之间的匹配办理。其间匹配的详细逻辑联络需求驱动规划着设定。
int (*uevent)(struct device *dev, char **envp, int num_envp,char *buffer, int buffer_size)则在热插拔事情之前,答应总线为设备增加环境变量。
一般创立一种总线类型的过程中只需完结总线类型结构体的填充,然后完结相应的注册、特点文件创立即可完结总线类型的增加。并不需求对bus_type类型中的一切变量进行赋值,只需将其间的name,bus_attribute,match完结即可。
最终不要忘了总线也是设备,需求将总线设备增加到内核中(注册函数)。
关于总线类型的特点设置,实质上便是完结一个结构体的操作。
如下源码所示:
struct bus_attribute {
/*特点结构体*/
struct attribute attr;
/*特点读操作函数,即显现函数*/
ssize_t (*show)(struct bus_type *bus, char *buf);
/*特点写操作函数,也便是存储到结构体中*/
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
/*能够经过宏命令界说一个总线结构体,可是需求自己完结特点读写操作函数,假如没有,可设置为NULL*/
/*总线特点界说宏*/
#define BUS_ATTR(_name, _mode, _show, _store)
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
/*__ATTR的宏完结如下所示:*/
#define __ATTR(_name,_mode,_show,_store) {
.attr = {.name = __stringify(_name), .mode = _mode },
.show = _show,
.store = _store,
}
因为一般情况下需求查找总线的版别信息,能够将版别信息增加到特点的读特点操作函数中,这样就能显现详细的版别信息。
在宏界说中##是指链接符的效果,相当于将两个部分链接起来,比方bus_attr_##name = bus_attr_name。这是在宏界说中比较常用的界说方法之一。
总线类型的注册和总线类型特点文件创立,以及总线设备的注册首要是根据下面几个函数来完结:
/*总线类型注册函数,因为可能会犯错,因而有必要对返回值进行查看*/
int __must_check bus_register(struct bus_type *bus);
/*总线类型开释函数*/
void bus_unregister(struct bus_type *bus);
/*总线文件特点创立函数,将相关的文件特点增加给总线类型,一起也有必要查看返回值是否正确*/
int __must_check bus_create_file(struct bus_type *,struct bus_attribute *);
/*总线类型文件特点删去函数,将两者之间的相关性堵截*/
void bus_remove_file(struct bus_type *, struct bus_attribute *);
最终需求将总线设备增加到体系中,首要选用设备注册函数;
设备注册函数:
int __must_check device_register(struct device *dev);
设备开释函数:
void device_unregister(struct device *dev);

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/317789.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部