微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > linux总线、设备和设备驱动的关系

linux总线、设备和设备驱动的关系

时间:12-15 来源:互联网 点击:

ldddev-> ldddev->dev.bus = &ldd_bus_type; //依赖的总线

ldddev->dev.parent = &ldd_bus; //父设备

ldddev->dev.release = ldd_dev_release;

strncpy(ldddev->dev.bus_id, ldddev->name, BUS_ID_SIZE); //设备名拷贝入device结构体中

return device_register(&ldddev->dev); //仍然用device_register注册,只不过上层打包了

}

EXPORT_SYMBOL(register_ldd_device);

void unregister_ldd_device(struct ldd_device *ldddev)

{

device_unregister(&ldddev->dev);

}

EXPORT_SYMBOL(unregister_ldd_device);

之三:device_driver

设备模型跟踪所有系统已知的驱动,主要目的是使驱动程序核心能协调驱动和新设备之间的关系。一旦驱动在系统中是已知的对象就可能完成大量的工作。驱动程序的结构体device_driver 定义如下:

struct device_driver {

const char *name;

struct bus_type *bus;

struct module *owner;

const char *mod_name;

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);

struct attribute_group **groups;

struct pm_ops *pm;

struct driver_private *p;

};

(1)驱动程序的注册和注销

int driver_register(struct device_driver *drv);

void driver_unregister(struct device_driver *drv);

(2)驱动程序的属性

struct driver_attribute {

struct attribute attr;

ssize_t (*show)(struct device_driver *drv, char *buf);

ssize_t (*store)(struct device_driver *drv, const char *buf, size_t count);

};

DRIVER_ATTR(_name,_mode,_show,_store)

*属性文件创建的方法:*/

int driver_create_file(struct device_driver * drv, struct driver_attribute * attr);

void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr);

(3)驱动程序结构的嵌入

对大多数驱动程序核心结构,device_driver 结构通常被嵌入到一个更高层的、总线相关的结构中。当然也有直接注册驱动的,不用嵌入到高层结构体。如driver_register(&wm97xx_driver)。

以lddbus 子系统为例,它定义了ldd_driver 结构:

struct ldd_driver {

char *version;

struct module *module;

struct device_driver driver;

struct driver_attribute version_attr;

};

#define to_ldd_driver(drv) container_of(drv, struct ldd_driver, driver);

lddbus总线中相关的驱动注册和注销函数是:

static ssize_t show_version(struct device_driver *driver, char *buf)

{

struct ldd_driver *ldriver = to_ldd_driver(driver);

sprintf(buf, "%s", ldriver->version);

return strlen(buf);

}

int register_ldd_driver(struct ldd_driver *driver) //device_driver被嵌入到更高层结构体

{

int ret;

driver->driver.bus = &ldd_bus_type;

ret = driver_register(&driver->driver);

if (ret)

return ret;

driver->version_attr.attr.name = "version";

driver->version_attr.attr.owner = driver->module;

driver->version_attr.attr.mode = S_IRUGO;

driver->version_attr.show = show_version;

driver->version_attr.store = NULL;

return driver_create_file(&driver->driver, &driver->version_attr);

}

void unregister_ldd_driver(struct ldd_driver *driver)

{

driver_unregister(&driver->driver);

}

EXPORT_SYMBOL(register_ldd_driver);

EXPORT_SYMBOL(unregister_ldd_driver);

在sculld 中创建的 ldd_driver 结构如下:

static struct ldd_driver sculld_driver = {

.version = "$Revision: 1.21 $",

.module = THIS_MODULE,

.driver = {

.name = "sculld",

},

};

之四:class_register

类是一个设备的高层视图,它抽象出了底层的实现细节,从而允许用户空间使用设备所提供的功能,而不用关心设备是如何连接和工作的。类成员通常由上层代码所控制,而无需驱动的明确支持。但有些情况下驱动也需要直接处理类。

几乎所有的类都显示在/sys/class目录中,可以通过ls -l /sys/class来显示。出于历史的原因,有一个例外:块设备显示在/sys/block目录中。在许多情况,类子系统是向用户空间导出信息的最好方法。当类子系统创建一个类时,它将完全拥有这个类,根本不

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top